break everything part 2
This commit is contained in:
parent
ef7a94e51f
commit
e81b7612d7
2
Engine
2
Engine
@ -1 +1 @@
|
||||
Subproject commit 6babefb3017d33a78c914eda21fd1fa3b53dc9e3
|
||||
Subproject commit 7cda523891ce81b36dd5f09f5573e1f258f92923
|
@ -1 +1 @@
|
||||
Subproject commit 0da0d13c3dc8426b18a55107b42986e9d66387f1
|
||||
Subproject commit fceeea1cac7174f873834fa12b5d78952710a516
|
@ -1 +0,0 @@
|
||||
Subproject commit c36977964d2f203fe9a940df908d1b7c2fac264b
|
@ -1,23 +0,0 @@
|
||||
# TerraForgedAPI
|
||||
|
||||
### Dependency
|
||||
```groovy
|
||||
repositories {
|
||||
maven {
|
||||
url "https://io.terraforged.com/repository/maven/"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "com.terraforged:TerraForgedAPI:1.15.2-0.0.1"
|
||||
}
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
TerraForged fires a number of setup events each time its chunk generator is created. These events expose certain
|
||||
components of the generator allowing for world-gen content to be configured, modified, or added to.
|
||||
|
||||
See the `com.terraforged.api.TerraEvent` class for the available events.
|
||||
|
||||
All events are fired on the `FORGE` event bus.
|
@ -1,70 +0,0 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
maven { url "https://files.minecraftforge.net/maven" }
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath group: "net.minecraftforge.gradle", name: "ForgeGradle", version: "3.+", changing: true
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "net.minecraftforge.gradle"
|
||||
apply plugin: "maven-publish"
|
||||
apply plugin: "eclipse"
|
||||
|
||||
version = "${mc_version}-${mod_version}"
|
||||
archivesBaseName = "TerraForgedAPI"
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
minecraft "net.minecraftforge:forge:${mc_version}-${forge_version}"
|
||||
compile project(":FeatureManager")
|
||||
compile project(":TerraForgedCore")
|
||||
}
|
||||
|
||||
minecraft {
|
||||
mappings channel: mcp_channel, version: mcp_version
|
||||
}
|
||||
|
||||
task sourceJar(type: Jar) {
|
||||
classifier = "sources"
|
||||
from("$projectDir/src/main/java")
|
||||
from(project(":Noise2D").projectDir.getPath() + "/src/main/java")
|
||||
from(project(":FeatureManager").projectDir.getPath() + "/src/main/java")
|
||||
from(project(":TerraForgedCore").projectDir.getPath() + "/src/main/java")
|
||||
}
|
||||
|
||||
jar {
|
||||
dependsOn(sourceJar)
|
||||
from("$buildDir/classes/java/main")
|
||||
from(project(":Noise2D").buildDir.getPath() + "/classes/java/main")
|
||||
from(project(":FeatureManager").buildDir.getPath() + "/classes/java/main")
|
||||
from(project(":TerraForgedCore").buildDir.getPath() + "/classes/java/main")
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact jar
|
||||
artifact sourceJar
|
||||
}
|
||||
}
|
||||
|
||||
if (System.getenv("MAVEN_USER") != null && System.getenv("MAVEN_PASS") != null) {
|
||||
repositories {
|
||||
maven {
|
||||
credentials {
|
||||
username System.getenv("MAVEN_USER")
|
||||
password System.getenv("MAVEN_PASS")
|
||||
}
|
||||
name = "nexus"
|
||||
url = "https://io.terraforged.com/repository/maven/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.terraforged.api.material.state;
|
||||
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.tags.Tag;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class StateTagPredicate implements Predicate<BlockState> {
|
||||
|
||||
private final Tag<Block> tag;
|
||||
|
||||
public StateTagPredicate(Tag<Block> tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(BlockState state) {
|
||||
return tag.contains(state.getBlock());
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
apply plugin: "maven-publish"
|
||||
apply plugin: "java"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "com.google.code.gson:gson:2.8.0"
|
||||
compile "org.processing:core:3.3.7"
|
||||
compile "it.unimi.dsi:fastutil:8.2.1"
|
||||
compile project(":TerraForgedCore")
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest { attributes "Main-Class": "com.terraforged.app.Main" }
|
||||
from { configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
}
|
||||
|
||||
publish {
|
||||
dependsOn(jar)
|
||||
}
|
@ -1,161 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app;
|
||||
|
||||
import com.terraforged.app.renderer.MeshRenderer;
|
||||
import com.terraforged.app.renderer.Renderer;
|
||||
import com.terraforged.app.renderer.VoxelRenderer;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import processing.core.PApplet;
|
||||
import processing.event.KeyEvent;
|
||||
import processing.event.MouseEvent;
|
||||
|
||||
public abstract class Applet extends PApplet {
|
||||
|
||||
public static final int ELEVATION = 1;
|
||||
public static final int BIOME_TYPE = 2;
|
||||
public static final int TEMPERATURE = 3;
|
||||
public static final int MOISTURE = 4;
|
||||
public static final int BIOME = 5;
|
||||
public static final int STEEPNESS = 6;
|
||||
public static final int TERRAIN_TYPE = 7;
|
||||
public static final int EROSION = 8;
|
||||
public static final int CONTINENT = 9;
|
||||
|
||||
protected Renderer mesh = new MeshRenderer(this);
|
||||
protected Renderer voxel = new VoxelRenderer(this);
|
||||
|
||||
public final Controller controller = new Controller();
|
||||
|
||||
public abstract Cache getCache();
|
||||
|
||||
public abstract float color(Cell<Terrain> cell);
|
||||
|
||||
@Override
|
||||
public void settings() {
|
||||
size(800, 800, P3D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mousePressed(MouseEvent event) {
|
||||
controller.mousePress(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseReleased(MouseEvent event) {
|
||||
controller.mouseRelease(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(MouseEvent event) {
|
||||
controller.mouseDrag(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseWheel(MouseEvent event) {
|
||||
controller.mouseWheel(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent event) {
|
||||
controller.keyPress(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent event) {
|
||||
controller.keyRelease(event);
|
||||
}
|
||||
|
||||
public void leftAlignText(int margin, int top, int lineHeight, String... lines) {
|
||||
noLights();
|
||||
fill(0, 0, 100);
|
||||
for (int i = 0; i < lines.length; i++) {
|
||||
int y = top + (i * lineHeight);
|
||||
text(lines[i], margin, y);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void drawTerrain(float zoom) {
|
||||
if (controller.getRenderMode() == 0) {
|
||||
voxel.render(zoom);
|
||||
} else {
|
||||
mesh.render(zoom);
|
||||
}
|
||||
}
|
||||
|
||||
public String colorModeName() {
|
||||
switch (controller.getColorMode()) {
|
||||
case STEEPNESS:
|
||||
return "GRADIENT";
|
||||
case TEMPERATURE:
|
||||
return "TEMPERATURE";
|
||||
case MOISTURE:
|
||||
return "MOISTURE";
|
||||
case TERRAIN_TYPE:
|
||||
return "TERRAIN TYPE";
|
||||
case ELEVATION:
|
||||
return "ELEVATION";
|
||||
case BIOME_TYPE:
|
||||
return "BIOME TYPE";
|
||||
case BIOME:
|
||||
return "BIOME";
|
||||
case EROSION:
|
||||
return "EROSION";
|
||||
case CONTINENT:
|
||||
return "CONTINENT";
|
||||
default:
|
||||
return "-";
|
||||
}
|
||||
}
|
||||
|
||||
public static float hue(float value, int steps, int max) {
|
||||
value = Math.round(value * (steps - 1));
|
||||
value /= (steps - 1);
|
||||
return value * max;
|
||||
}
|
||||
|
||||
public void drawCompass() {
|
||||
pushStyle();
|
||||
pushMatrix();
|
||||
textSize(200);
|
||||
fill(100, 0, 100);
|
||||
|
||||
char[] chars = {'N', 'E', 'S', 'W'};
|
||||
for (int r = 0; r < 4; r++) {
|
||||
char c = chars[r];
|
||||
float x = -textWidth(c) / 2;
|
||||
float y = -width * 1.2F;
|
||||
text(c, x, y);
|
||||
rotateZ(0.5F * PI);
|
||||
}
|
||||
|
||||
popMatrix();
|
||||
popStyle();
|
||||
textSize(16);
|
||||
}
|
||||
}
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.region.Region;
|
||||
import com.terraforged.core.region.gen.RegionGenerator;
|
||||
import com.terraforged.core.settings.Settings;
|
||||
import com.terraforged.core.util.concurrent.ThreadPool;
|
||||
import com.terraforged.core.world.GeneratorContext;
|
||||
import com.terraforged.core.world.WorldGeneratorFactory;
|
||||
import com.terraforged.core.world.biome.BiomeType;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import com.terraforged.core.world.terrain.Terrains;
|
||||
|
||||
public class Cache {
|
||||
|
||||
private float offsetX = 0;
|
||||
private float offsetZ = 0;
|
||||
private float zoom = 0F;
|
||||
private boolean filter = true;
|
||||
private Terrains terrain;
|
||||
private Settings settings;
|
||||
private GeneratorContext context;
|
||||
private Region region;
|
||||
private RegionGenerator renderer;
|
||||
|
||||
public Cache(int seed) {
|
||||
Settings settings = new Settings();
|
||||
settings.generator.seed = seed;
|
||||
this.settings = settings;
|
||||
this.terrain = Terrains.create(settings);
|
||||
this.context = new GeneratorContext(terrain, settings);
|
||||
this.renderer = RegionGenerator.builder()
|
||||
.factory(new WorldGeneratorFactory(context))
|
||||
.pool(ThreadPool.getPool())
|
||||
.size(3, 2)
|
||||
.build();
|
||||
}
|
||||
|
||||
public Settings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
public Terrains getTerrain() {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public Terrain getCenterTerrain() {
|
||||
Terrain tag = getCenterCell().tag;
|
||||
return tag == null ? terrain.ocean : tag;
|
||||
}
|
||||
|
||||
public BiomeType getCenterBiomeType() {
|
||||
return getCenterCell().biomeType;
|
||||
}
|
||||
|
||||
public int getCenterHeight() {
|
||||
return (int) (context.levels.worldHeight * getCenterCell().value);
|
||||
}
|
||||
|
||||
public Cell<Terrain> getCenterCell() {
|
||||
int center = region.getBlockSize().size / 2;
|
||||
return region.getCell(center, center);
|
||||
}
|
||||
|
||||
public Region getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
public void update(float offsetX, float offsetZ, float zoom, boolean filters) {
|
||||
if (region == null) {
|
||||
record(offsetX, offsetZ, zoom, filters);
|
||||
return;
|
||||
}
|
||||
if (this.offsetX != offsetX || this.offsetZ != offsetZ) {
|
||||
record(offsetX, offsetZ, zoom, filters);
|
||||
return;
|
||||
}
|
||||
if (this.zoom != zoom) {
|
||||
record(offsetX, offsetZ, zoom, filters);
|
||||
return;
|
||||
}
|
||||
if (this.filter != filters) {
|
||||
record(offsetX, offsetZ, zoom, filters);
|
||||
}
|
||||
}
|
||||
|
||||
private void record(float offsetX, float offsetZ, float zoom, boolean filters) {
|
||||
this.zoom = zoom;
|
||||
this.filter = filters;
|
||||
this.offsetX = offsetX;
|
||||
this.offsetZ = offsetZ;
|
||||
try {
|
||||
this.region = renderer.generateRegion(offsetX, offsetZ, zoom, filters);
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,236 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app;
|
||||
|
||||
import processing.core.PApplet;
|
||||
import processing.event.KeyEvent;
|
||||
import processing.event.MouseEvent;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
|
||||
public class Controller {
|
||||
|
||||
private static final int BUTTON_NONE = -1;
|
||||
private static final int BUTTON_1 = 37;
|
||||
private static final int BUTTON_2 = 39;
|
||||
private static final int BUTTON_3 = 3;
|
||||
|
||||
private static final float cameraSpeed = 100F;
|
||||
private static final float zoomSpeed = 0.01F;
|
||||
private static final float rotateSpeed = 0.002F;
|
||||
private static final float translateSpeed = 2F;
|
||||
private static final float moveSpeed = 10F;
|
||||
|
||||
private int mouseButton = BUTTON_NONE;
|
||||
private int lastX = 0;
|
||||
private int lastY = 0;
|
||||
|
||||
private float yaw = -0.2F;
|
||||
private float pitch = 0.85F;
|
||||
private float translateX = 0F;
|
||||
private float translateY = 0F;
|
||||
private float translateZ = -800;
|
||||
private float velocityX = 0F;
|
||||
private float velocityY = 0F;
|
||||
|
||||
private int colorMode = 1;
|
||||
private int renderMode = 0;
|
||||
private int newSeed = 0;
|
||||
private int left = 0;
|
||||
private int right = 0;
|
||||
private int up = 0;
|
||||
private int down = 0;
|
||||
private float zoom = 16;
|
||||
private boolean filters = true;
|
||||
|
||||
public void apply(PApplet applet) {
|
||||
applet.translate(translateX, translateY, translateZ);
|
||||
applet.translate(applet.width / 2, applet.height / 2, 0);
|
||||
applet.rotateX(pitch);
|
||||
applet.rotateZ(yaw);
|
||||
update();
|
||||
}
|
||||
|
||||
public void update() {
|
||||
float forward = up + down;
|
||||
float strafe = left + right;
|
||||
velocityX = forward * (float) Math.sin(yaw);
|
||||
velocityY = forward * (float) Math.cos(yaw);
|
||||
velocityX += strafe * (float) Math.sin(yaw + Math.toRadians(90));
|
||||
velocityY += strafe * (float) Math.cos(yaw + Math.toRadians(90));
|
||||
if (velocityX != 0 || velocityY != 0) {
|
||||
float magnitude = (float) Math.sqrt(velocityX * velocityX + velocityY * velocityY);
|
||||
velocityX /= magnitude;
|
||||
velocityY /= magnitude;
|
||||
}
|
||||
}
|
||||
|
||||
public int getColorMode() {
|
||||
return colorMode;
|
||||
}
|
||||
|
||||
public int getRenderMode() {
|
||||
return renderMode;
|
||||
}
|
||||
|
||||
public float velocityX() {
|
||||
return velocityX * moveSpeed / zoom;
|
||||
}
|
||||
|
||||
public float velocityY() {
|
||||
return velocityY * moveSpeed / zoom;
|
||||
}
|
||||
|
||||
public float zoomLevel() {
|
||||
return zoom;
|
||||
}
|
||||
|
||||
public boolean filters() {
|
||||
return filters;
|
||||
}
|
||||
|
||||
public int getNewSeed() {
|
||||
if (newSeed == 1) {
|
||||
newSeed = 0;
|
||||
return 1;
|
||||
}
|
||||
if (newSeed != 0) {
|
||||
int val = newSeed;
|
||||
newSeed = 0;
|
||||
return val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void keyPress(KeyEvent event) {
|
||||
switch (event.getKey()) {
|
||||
case 'w':
|
||||
up = -1;
|
||||
break;
|
||||
case 'a':
|
||||
left = -1;
|
||||
break;
|
||||
case 's':
|
||||
down = 1;
|
||||
break;
|
||||
case 'd':
|
||||
right = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void keyRelease(KeyEvent event) {
|
||||
switch (event.getKey()) {
|
||||
case 'w':
|
||||
up = 0;
|
||||
return;
|
||||
case 'a':
|
||||
left = 0;
|
||||
return;
|
||||
case 's':
|
||||
down = 0;
|
||||
return;
|
||||
case 'd':
|
||||
right = 0;
|
||||
return;
|
||||
case 'r':
|
||||
renderMode = renderMode == 0 ? 1 : 0;
|
||||
return;
|
||||
case 'n':
|
||||
newSeed = 1;
|
||||
return;
|
||||
case 'm':
|
||||
newSeed = Main.seed;
|
||||
return;
|
||||
case 'f':
|
||||
filters = !filters;
|
||||
return;
|
||||
case 'c':
|
||||
StringSelection selection = new StringSelection("" + Main.seed);
|
||||
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, null);
|
||||
return;
|
||||
case 'v':
|
||||
try {
|
||||
Object data = Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
|
||||
newSeed = (int) Long.parseLong(data.toString());
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getKey() >= '1' && event.getKey() <= '9') {
|
||||
colorMode = event.getKey() - '0';
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void mousePress(MouseEvent event) {
|
||||
if (mouseButton == BUTTON_NONE) {
|
||||
lastX = event.getX();
|
||||
lastY = event.getY();
|
||||
mouseButton = event.getButton();
|
||||
}
|
||||
}
|
||||
|
||||
public void mouseRelease(MouseEvent event) {
|
||||
mouseButton = BUTTON_NONE;
|
||||
}
|
||||
|
||||
public void mouseWheel(MouseEvent event) {
|
||||
translateZ -= event.getCount() * cameraSpeed;
|
||||
}
|
||||
|
||||
public void mouseDrag(MouseEvent event) {
|
||||
int dx = event.getX() - lastX;
|
||||
int dy = event.getY() - lastY;
|
||||
boolean ctrl = (event.getModifiers() & ActionEvent.CTRL_MASK) == ActionEvent.CTRL_MASK;
|
||||
|
||||
lastX = event.getX();
|
||||
lastY = event.getY();
|
||||
|
||||
if (mouseButton == BUTTON_1) {
|
||||
yaw -= dx * rotateSpeed;
|
||||
pitch -= dy * rotateSpeed;
|
||||
}
|
||||
|
||||
if (mouseButton == BUTTON_2) {
|
||||
translateX += dx * translateSpeed;
|
||||
translateY += dy * translateSpeed;
|
||||
}
|
||||
|
||||
if (mouseButton == BUTTON_3) {
|
||||
if (ctrl) {
|
||||
zoom += (dy - dx) * zoom * zoomSpeed;
|
||||
zoom = Math.max(1F, zoom);
|
||||
} else {
|
||||
translateZ -= (dy - dx) * cameraSpeed * 0.1F;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,264 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app;
|
||||
|
||||
import com.terraforged.app.biome.BiomeProvider;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.biome.BiomeData;
|
||||
import com.terraforged.core.world.biome.BiomeType;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.Random;
|
||||
|
||||
public class Main extends Applet {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Main.start(-1);
|
||||
}
|
||||
|
||||
public static void start(long seed) {
|
||||
Main.seed = (int) seed;
|
||||
Main.random = seed == -1;
|
||||
main(Main.class.getName());
|
||||
}
|
||||
|
||||
private static boolean random = false;
|
||||
public static int seed = -1;
|
||||
|
||||
private Cache cache;
|
||||
private float offsetX = 0;
|
||||
private float offsetZ = 0;
|
||||
private final String bits = System.getProperty("sun.arch.data.model");
|
||||
private final BiomeProvider biomeProvider = new BiomeProvider();
|
||||
|
||||
@Override
|
||||
public Cache getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup() {
|
||||
super.setup();
|
||||
if (random) {
|
||||
setSeed(new Random(System.currentTimeMillis()).nextInt());
|
||||
offsetX = 0;
|
||||
offsetZ = 0;
|
||||
}
|
||||
setSeed(seed);
|
||||
}
|
||||
|
||||
public void setSeed(int seed) {
|
||||
Main.seed = seed;
|
||||
cache = new Cache(seed);
|
||||
System.out.println(seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public float color(Cell<Terrain> cell) {
|
||||
switch (controller.getColorMode()) {
|
||||
case STEEPNESS:
|
||||
return hue(1 - cell.steepness, 64, 70);
|
||||
case TEMPERATURE:
|
||||
return hue(1 - cell.temperature, 64, 70);
|
||||
case MOISTURE:
|
||||
return hue(cell.moisture, 64, 70);
|
||||
case TERRAIN_TYPE:
|
||||
if (cell.tag == getCache().getTerrain().volcano) {
|
||||
return 0F;
|
||||
}
|
||||
return 20 + (cell.tag.getHue() * 80);
|
||||
case ELEVATION:
|
||||
float value = (cell.value - 0.245F) / 0.65F;
|
||||
return (1 - value) * 30;
|
||||
case BIOME:
|
||||
BiomeData biome = biomeProvider.getBiome(cell);
|
||||
if (biome == null) {
|
||||
return 0F;
|
||||
}
|
||||
return cell.biome * 70;
|
||||
case CONTINENT:
|
||||
return cell.continent * 70;
|
||||
default:
|
||||
return 50;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw() {
|
||||
int nextSeed = controller.getNewSeed();
|
||||
if (nextSeed == 1) {
|
||||
setup();
|
||||
} else if (nextSeed != 0) {
|
||||
setSeed(nextSeed);
|
||||
}
|
||||
|
||||
offsetX += controller.velocityX() * controller.zoomLevel() * controller.zoomLevel();
|
||||
offsetZ += controller.velocityY() * controller.zoomLevel() * controller.zoomLevel();
|
||||
cache.update(offsetX, offsetZ, controller.zoomLevel(), controller.filters());
|
||||
|
||||
// color stuff
|
||||
noStroke();
|
||||
background(0);
|
||||
colorMode(HSB, 100);
|
||||
|
||||
// lighting
|
||||
ambientLight(0, 0, 75, width / 2, -height, height / 2);
|
||||
pointLight(0, 0, 50, width / 2, -height * 100, height / 2);
|
||||
|
||||
// render
|
||||
pushMatrix();
|
||||
controller.apply(this);
|
||||
// translate(-width / 2F, -height / 2F);
|
||||
drawTerrain(controller.zoomLevel());
|
||||
drawCompass();
|
||||
// translate(0, 0, 255 * (width / (float) controller.resolution()) / controller.zoomLevel());
|
||||
// mesh.renderWind(controller.resolution(), controller.zoomLevel());
|
||||
popMatrix();
|
||||
|
||||
pushMatrix();
|
||||
translate(0, 0, -1);
|
||||
// drawGradient(0, height - 150, 100F, width, 150);
|
||||
popMatrix();
|
||||
|
||||
drawStats();
|
||||
drawBiomeKey();
|
||||
drawControls();
|
||||
}
|
||||
|
||||
private void drawGradient(int x, int y, float d, float w, float h) {
|
||||
noFill();
|
||||
for (int dy = 0; dy <= h; dy++) {
|
||||
float dist = Math.min(1, dy / d);
|
||||
stroke(0, 0, 0, dist * 100F);
|
||||
line(x, y + dy, x + w, y + dy);
|
||||
}
|
||||
noStroke();
|
||||
}
|
||||
|
||||
private void drawStats() {
|
||||
int resolution = cache.getRegion().getBlockSize().size;
|
||||
int blocks = NoiseUtil.round(resolution * controller.zoomLevel());
|
||||
|
||||
String[][] info = {
|
||||
{"Java:", String.format("x%s", bits)},
|
||||
{"Fps: ", String.format("%.3f", frameRate)},
|
||||
{"Seed:", String.format("%s", seed)},
|
||||
{"Zoom: ", String.format("%.2f", controller.zoomLevel())},
|
||||
{"Area: ", String.format("%sx%s [%sx%s]", blocks, blocks, resolution, resolution)},
|
||||
{"Center: ", String.format("x=%.0f, y=%s, z=%.0f", offsetX, cache.getCenterHeight(), offsetZ)},
|
||||
{"Terrain: ", cache.getCenterTerrain().getName()},
|
||||
{"BiomeType:", cache.getCenterBiomeType().name()},
|
||||
// {"Biome: ", String.format("%s", biomeProvider.getBiome(cache.getCenterCell()).name)},
|
||||
{"Overlay: ", colorModeName()},
|
||||
};
|
||||
|
||||
int widest = 0;
|
||||
for (String[] s : info) {
|
||||
widest = Math.max(widest, (int) textWidth(s[0]));
|
||||
}
|
||||
|
||||
int top = 20;
|
||||
int lineHeight = 15;
|
||||
for (String[] s : info) {
|
||||
leftAlignText(10, top, 0, s[0]);
|
||||
top += lineHeight;
|
||||
}
|
||||
|
||||
top = 20;
|
||||
for (String[] s : info) {
|
||||
if (s.length == 2) {
|
||||
leftAlignText(12 + widest, top, 0, s[1]);
|
||||
top += lineHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawBiomeKey() {
|
||||
int top = 20;
|
||||
int lineHeight = 15;
|
||||
int widest = 0;
|
||||
for (BiomeType type : BiomeType.values()) {
|
||||
widest = Math.max(widest, (int) textWidth(type.name()));
|
||||
}
|
||||
|
||||
int left = width - widest - lineHeight - 15;
|
||||
for (BiomeType type : BiomeType.values()) {
|
||||
leftAlignText(left, top, 0, type.name());
|
||||
float[] hsb = Color.RGBtoHSB(type.getColor().getRed(), type.getColor().getGreen(),
|
||||
type.getColor().getBlue(), null);
|
||||
fill(0, 0, 100);
|
||||
rect(width - lineHeight - 11, top - lineHeight + 1, lineHeight + 2, lineHeight + 2);
|
||||
|
||||
fill(hsb[0] * 100, hsb[1] * 100, hsb[2] * 100);
|
||||
rect(width - lineHeight - 10, top - lineHeight + 2, lineHeight, lineHeight);
|
||||
top += lineHeight;
|
||||
}
|
||||
}
|
||||
|
||||
private void drawControls() {
|
||||
String[][][] columns = {
|
||||
{
|
||||
{"Mouse-Left + Move", " - Rotate terrain"},
|
||||
{"Mouse-Right + Move", " - Pan terrain"},
|
||||
{"Mouse-Scroll + Move", " - Zoom camera"},
|
||||
{"Mouse-Scroll + LCTRL + Move", " - Zoom terrain"},
|
||||
{"WASD", "- Move terrain"}
|
||||
}, {
|
||||
{"Key 1-8", "- Select overlay"},
|
||||
{"Key R", "- Toggle mesh renderer"},
|
||||
{"Key F", "- Toggle filters"},
|
||||
{"Key N", "- Generate new world"},
|
||||
{"Key C", "- Copy seed to clipboard"},
|
||||
{"Key V", "- Paste seed from clipboard"},
|
||||
}};
|
||||
|
||||
int lineHeight = 15;
|
||||
int rows = 0;
|
||||
for (String[][] column : columns) {
|
||||
rows = Math.max(rows, column.length);
|
||||
}
|
||||
|
||||
int left = 10;
|
||||
int widest = 0;
|
||||
for (String[][] column : columns) {
|
||||
int top = (height - 10) - ((rows - 1) * lineHeight);
|
||||
|
||||
for (String[] row : column) {
|
||||
int width = 0;
|
||||
for (String cell : row) {
|
||||
leftAlignText(left + width, top, 0, cell);
|
||||
width += (int) textWidth(cell);
|
||||
}
|
||||
top += lineHeight;
|
||||
widest = Math.max(widest, width);
|
||||
}
|
||||
|
||||
left += widest + 10;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app.biome;
|
||||
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class BiomeColor {
|
||||
|
||||
private static final BufferedImage image = load();
|
||||
private static final int width = image.getWidth() - 1;
|
||||
private static final int height = image.getHeight() - 1;
|
||||
|
||||
public static int getRGB(float temp, float moist) {
|
||||
float humidity = temp * moist;
|
||||
temp = 1 - temp;
|
||||
humidity = 1 - humidity;
|
||||
int x = NoiseUtil.round(temp * width);
|
||||
int y = NoiseUtil.round(humidity * height);
|
||||
return image.getRGB(x, y);
|
||||
}
|
||||
|
||||
|
||||
private static BufferedImage load() {
|
||||
try (InputStream inputStream = BiomeColor.class.getResourceAsStream("/grass.png")) {
|
||||
return ImageIO.read(inputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app.biome;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.util.grid.FixedGrid;
|
||||
import com.terraforged.core.world.biome.BiomeData;
|
||||
import com.terraforged.core.world.biome.BiomeType;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import processing.data.JSONArray;
|
||||
import processing.data.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BiomeProvider {
|
||||
|
||||
private final List<FixedGrid<BiomeData>> biomes;
|
||||
|
||||
public BiomeProvider() {
|
||||
biomes = getBiomes(5);
|
||||
}
|
||||
|
||||
public BiomeData getBiome(Cell<Terrain> cell) {
|
||||
FixedGrid<BiomeData> grid = biomes.get(cell.biomeType.ordinal());
|
||||
if (grid == null) {
|
||||
return null;
|
||||
}
|
||||
return grid.get(cell.moisture, cell.temperature, cell.biome);
|
||||
}
|
||||
|
||||
private static List<FixedGrid<BiomeData>> getBiomes(int gridSize) {
|
||||
List<FixedGrid<BiomeData>> data = new ArrayList<>();
|
||||
for (BiomeType type : BiomeType.values()) {
|
||||
data.add(type.ordinal(), null);
|
||||
}
|
||||
|
||||
Map<String, BiomeData> biomes = loadBiomes();
|
||||
Map<BiomeType, List<String>> types = loadBiomeTypes();
|
||||
for (Map.Entry<BiomeType, List<String>> e : types.entrySet()) {
|
||||
List<BiomeData> list = new LinkedList<>();
|
||||
for (String id : e.getValue()) {
|
||||
BiomeData biome = biomes.get(id);
|
||||
if (biome != null) {
|
||||
list.add(biome);
|
||||
}
|
||||
}
|
||||
FixedGrid<BiomeData> grid = FixedGrid.generate(gridSize, list, b -> b.rainfall, b -> b.temperature);
|
||||
data.set(e.getKey().ordinal(), grid);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
private static Map<String, BiomeData> loadBiomes() {
|
||||
try (InputStream inputStream = BiomeProvider.class.getResourceAsStream("/biome_data.json")) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
reader.lines().forEach(sb::append);
|
||||
JSONArray array = JSONArray.parse(sb.toString());
|
||||
Map<String,BiomeData> biomes = new HashMap<>();
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
JSONObject object = array.getJSONObject(i);
|
||||
String name = object.getString("id");
|
||||
float moisture = object.getFloat("moisture");
|
||||
float temperature = object.getFloat("temperature");
|
||||
int color = BiomeColor.getRGB(temperature, moisture);
|
||||
BiomeData biome = new BiomeData(name, null, color, moisture, temperature);
|
||||
biomes.put(name, biome);
|
||||
}
|
||||
return biomes;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<BiomeType, List<String>> loadBiomeTypes() {
|
||||
try (InputStream inputStream = BiomeProvider.class.getResourceAsStream("/biome_groups.json")) {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
|
||||
StringBuilder sb = new StringBuilder();
|
||||
reader.lines().forEach(sb::append);
|
||||
JSONObject object = JSONObject.parse(sb.toString());
|
||||
Iterator iterator = object.keyIterator();
|
||||
Map<BiomeType, List<String>> biomes = new HashMap<>();
|
||||
while (iterator.hasNext()) {
|
||||
String key = "" + iterator.next();
|
||||
if (key.contains("rivers")) {
|
||||
continue;
|
||||
}
|
||||
if (key.contains("oceans")) {
|
||||
continue;
|
||||
}
|
||||
BiomeType type = BiomeType.valueOf(key);
|
||||
List<String> group = new LinkedList<>();
|
||||
JSONArray array = object.getJSONArray(key);
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
group.add(array.getString(i));
|
||||
}
|
||||
biomes.put(type, group);
|
||||
}
|
||||
return biomes;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,141 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app.mesh;
|
||||
|
||||
public class Mesh {
|
||||
|
||||
private final Mesh inner;
|
||||
private final float x0;
|
||||
private final float y0;
|
||||
private final float x1;
|
||||
private final float y1;
|
||||
private final float quality;
|
||||
|
||||
public Mesh(Mesh inner, float x0, float y0, float x1, float y1, float quality) {
|
||||
this.inner = inner;
|
||||
this.x0 = x0;
|
||||
this.y0 = y0;
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
this.quality = quality;
|
||||
}
|
||||
|
||||
public Mesh expand(float scale) {
|
||||
return expand(scale, scale);
|
||||
}
|
||||
|
||||
public Mesh expand(float scale, float quality) {
|
||||
float width0 = getWidth();
|
||||
float height0 = getHeight();
|
||||
float width1 = width0 * scale;
|
||||
float height1 = height0 * scale;
|
||||
float deltaX = (width1 - width0) / 2F;
|
||||
float deltaY = (height1 - height0) / 2F;
|
||||
float newQuality = this.quality * quality;
|
||||
return new Mesh(this, x0 - deltaX, y0 - deltaY, x1 + deltaX, y1 + deltaY, newQuality);
|
||||
}
|
||||
|
||||
public float getWidth() {
|
||||
return x1 - x0;
|
||||
}
|
||||
|
||||
public float getHeight() {
|
||||
return y1 - y0;
|
||||
}
|
||||
|
||||
public void start(float width, float height) {
|
||||
if (inner != null) {
|
||||
inner.start(width, height);
|
||||
}
|
||||
}
|
||||
|
||||
public void render() {
|
||||
if (inner == null) {
|
||||
renderNormal();
|
||||
} else {
|
||||
renderCutout();
|
||||
inner.render();
|
||||
}
|
||||
}
|
||||
|
||||
public void beginStrip() {
|
||||
if (inner != null) {
|
||||
inner.beginStrip();
|
||||
}
|
||||
}
|
||||
|
||||
public void endStrip() {
|
||||
if (inner != null) {
|
||||
inner.endStrip();
|
||||
}
|
||||
}
|
||||
|
||||
public void visit(float x, float y) {
|
||||
if (inner != null) {
|
||||
inner.visit(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderNormal() {
|
||||
beginStrip();
|
||||
iterate(x0, y0, x1, y1);
|
||||
endStrip();
|
||||
}
|
||||
|
||||
private void renderCutout() {
|
||||
beginStrip();
|
||||
iterate(x0, y0, inner.x1, inner.y0);
|
||||
endStrip();
|
||||
|
||||
beginStrip();
|
||||
iterate(inner.x1, y0, x1, inner.y1);
|
||||
endStrip();
|
||||
|
||||
beginStrip();
|
||||
iterate(inner.x0, inner.y1, x1, y1);
|
||||
endStrip();
|
||||
|
||||
beginStrip();
|
||||
iterate(x0, inner.y0, inner.x0, y1);
|
||||
endStrip();
|
||||
}
|
||||
|
||||
private void iterate(float minX, float minY, float maxX, float maxY) {
|
||||
float x = minX - quality;
|
||||
float y = minY - quality;
|
||||
while (y < maxY) {
|
||||
y = Math.min(y + quality, maxY);
|
||||
beginStrip();
|
||||
while (x < maxX) {
|
||||
x = Math.min(x + quality, maxX);
|
||||
visit(x, y);
|
||||
visit(x, y + quality);
|
||||
}
|
||||
x = minX - quality;
|
||||
endStrip();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app.mesh;
|
||||
|
||||
import com.terraforged.app.Applet;
|
||||
import com.terraforged.app.renderer.Renderer;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import processing.core.PApplet;
|
||||
|
||||
public class NoiseMesh extends Mesh {
|
||||
|
||||
private final Applet applet;
|
||||
private final Renderer renderer;
|
||||
private final Cell<Terrain> cell = new Cell<>();
|
||||
|
||||
public NoiseMesh(Applet applet, Renderer renderer, float x0, float y0, float x1, float y1) {
|
||||
super(null, x0, y0, x1, y1, 1F);
|
||||
this.applet = applet;
|
||||
this.renderer = renderer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(float width, float height) {
|
||||
applet.noStroke();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginStrip() {
|
||||
applet.beginShape(PApplet.TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endStrip() {
|
||||
applet.endShape();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(float x, float y) {
|
||||
float height = cell.value * 255;
|
||||
float surface = renderer.getSurface(cell, height, 63, 10F);
|
||||
applet.vertex(x * 10F, y * 10F, (int) surface);
|
||||
}
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app.mesh;
|
||||
|
||||
import com.terraforged.app.Applet;
|
||||
import com.terraforged.app.renderer.Renderer;
|
||||
|
||||
public class TestRenderer extends Renderer {
|
||||
|
||||
private static boolean printed = false;
|
||||
|
||||
public TestRenderer(Applet visualizer) {
|
||||
super(visualizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float zoom) {
|
||||
Mesh mesh = new NoiseMesh(applet, this, -64, -64, 64, 64);
|
||||
for (int i = 0; i < 1; i++) {
|
||||
// mesh = mesh.expand(4);
|
||||
}
|
||||
|
||||
float width = mesh.getWidth();
|
||||
float height = mesh.getHeight();
|
||||
if (!printed) {
|
||||
printed = true;
|
||||
System.out.println(width + "x" + height);
|
||||
}
|
||||
|
||||
applet.pushMatrix();
|
||||
mesh.start(mesh.getWidth(), mesh.getHeight());
|
||||
mesh.render();
|
||||
applet.popMatrix();
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app.renderer;
|
||||
|
||||
import com.terraforged.app.Applet;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.heightmap.Levels;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import processing.core.PApplet;
|
||||
|
||||
public class MeshRenderer extends Renderer {
|
||||
|
||||
public MeshRenderer(Applet visualizer) {
|
||||
super(visualizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float zoom) {
|
||||
float seaLevel = new Levels(applet.getCache().getSettings().generator).water;
|
||||
int worldHeight = applet.getCache().getSettings().generator.world.worldHeight;
|
||||
int waterLevel = (int) (seaLevel * worldHeight);
|
||||
int seabedLevel = (int) ((seaLevel - 0.04) * worldHeight);
|
||||
int resolution = applet.getCache().getRegion().getBlockSize().size;
|
||||
|
||||
float w = applet.width / (float) (resolution - 1);
|
||||
float h = applet.width / (float) (resolution - 1);
|
||||
|
||||
applet.noStroke();
|
||||
applet.pushMatrix();
|
||||
applet.translate(-applet.width / 2F, -applet.width / 2F);
|
||||
|
||||
for (int dy = 0; dy < resolution - 1; dy++) {
|
||||
applet.beginShape(PApplet.TRIANGLE_STRIP);
|
||||
for (int dx = 0; dx < resolution; dx++) {
|
||||
draw(dx, dy, w, h, zoom, worldHeight, waterLevel, seabedLevel);
|
||||
draw(dx, dy + 1, w, h, zoom, worldHeight, waterLevel, resolution / 2);
|
||||
}
|
||||
applet.endShape();
|
||||
}
|
||||
|
||||
applet.popMatrix();
|
||||
}
|
||||
|
||||
private void draw(int dx, int dz, float w, float h, float zoom, int worldHeight, int waterLevel, int center) {
|
||||
Cell<Terrain> cell = applet.getCache().getRegion().getCell(dx, dz);
|
||||
float height = (cell.value * worldHeight);
|
||||
float x = dx * w;
|
||||
float z = dz * h;
|
||||
float y = (int) getSurface(cell, height, waterLevel, 1);
|
||||
applet.vertex(x, z, y / (zoom * 0.2F));
|
||||
}
|
||||
}
|
@ -1,133 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app.renderer;
|
||||
|
||||
import com.terraforged.app.Applet;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public abstract class Renderer {
|
||||
|
||||
protected final Applet applet;
|
||||
|
||||
protected Renderer(Applet visualizer) {
|
||||
this.applet = visualizer;
|
||||
}
|
||||
|
||||
public float getSurface(Cell<Terrain> cell, float height, int waterLevel, float el) {
|
||||
if (cell.tag == applet.getCache().getTerrain().volcanoPipe) {
|
||||
applet.fill(2, 80, 64);
|
||||
return height * 0.95F * el;
|
||||
}
|
||||
if (height < waterLevel) {
|
||||
float temp = cell.temperature;
|
||||
float tempDelta = temp > 0.5 ? temp - 0.5F : -(0.5F - temp);
|
||||
float tempAlpha = (tempDelta / 0.5F);
|
||||
float hueMod = 4 * tempAlpha;
|
||||
|
||||
float depth = (waterLevel - height) / (float) (90);
|
||||
float darkness = (1 - depth);
|
||||
float darknessMod = 0.5F + (darkness * 0.5F);
|
||||
|
||||
applet.fill(60 - hueMod, 65, 90 * darknessMod);
|
||||
return height * el;
|
||||
} else if (applet.controller.getColorMode() == Applet.ELEVATION) {
|
||||
float hei = Math.min(1, Math.max(0, height - waterLevel) / (255F - waterLevel));
|
||||
float temp = cell.temperature;
|
||||
float moist = Math.min(temp, cell.moisture);
|
||||
|
||||
float hue = 35 - (temp * (1 - moist)) * 25;
|
||||
float sat = 75 * (1 - hei);
|
||||
float bri = 50 + 40 * hei;
|
||||
applet.fill(hue, sat, bri);
|
||||
return height * el;
|
||||
} else if (applet.controller.getColorMode() == Applet.BIOME_TYPE) {
|
||||
Color c = cell.biomeType.getColor();
|
||||
if (cell.riverMask < 0.025) {
|
||||
c = Color.white;
|
||||
}
|
||||
float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
|
||||
float bri = 90 + cell.biomeTypeMask * 10;
|
||||
applet.fill(hsb[0] * 100, hsb[1] * 100, hsb[2] * bri);
|
||||
return height * el;
|
||||
} else if (applet.controller.getColorMode() == Applet.BIOME) {
|
||||
float hue = applet.color(cell);
|
||||
float sat = 70;
|
||||
float bright = 50 + 50 * cell.riverMask;
|
||||
applet.fill(hue, sat, bright);
|
||||
return height * el;
|
||||
} else if(applet.controller.getColorMode() == Applet.TERRAIN_TYPE) {
|
||||
float hue = applet.color(cell);
|
||||
if (cell.tag == applet.getCache().getTerrain().coast) {
|
||||
hue = 15;
|
||||
}
|
||||
float modifier = cell.mask(0.4F, 0.5F, 0F, 1F);
|
||||
float modAlpha = 0.1F;
|
||||
float mod = (1 - modAlpha) + (modifier * modAlpha);
|
||||
float sat = 70;
|
||||
float bri = 70;
|
||||
applet.fill(hue, 65, 70);
|
||||
return height * el;
|
||||
} else if(applet.controller.getColorMode() == Applet.EROSION) {
|
||||
float change = cell.sediment + cell.erosion;
|
||||
float value = Math.abs(cell.sediment * 250);
|
||||
value = Math.max(0, Math.min(1, value));
|
||||
float hue = value * 70;
|
||||
float sat = 70;
|
||||
float bri = 70;
|
||||
applet.fill(hue, sat, bri);
|
||||
return height * el;
|
||||
} else {
|
||||
float hue = applet.color(cell);
|
||||
float sat = 70;
|
||||
float bri = 70;
|
||||
applet.fill(hue, sat, bri);
|
||||
return height * el;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void render(float zoom);
|
||||
|
||||
private void renderGradLine(int steps, float x1, float y1, float x2, float y2, float hue1, float hue2, float sat, float bright) {
|
||||
float dx = x2 - x1;
|
||||
float dy = y2 - y1;
|
||||
float fx = dx / steps;
|
||||
float fy = dy / steps;
|
||||
float dhue = hue2 - hue1;
|
||||
float fhue = dhue / steps;
|
||||
for (int i = 0; i < steps; i++) {
|
||||
float px1 = x1 + (i * fx);
|
||||
float py1 = y1 + (i * fy);
|
||||
float px2 = x2 + ((i + 1) * fx);
|
||||
float py2 = y2 + ((i + 1) * fy);
|
||||
float hue = (i + 1) * fhue;
|
||||
applet.stroke(hue1 + hue, sat, bright);
|
||||
applet.line(px1, py1, px2, py2);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.app.renderer;
|
||||
|
||||
import com.terraforged.app.Applet;
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.heightmap.Levels;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import processing.core.PApplet;
|
||||
|
||||
public class VoxelRenderer extends Renderer {
|
||||
|
||||
public VoxelRenderer(Applet visualizer) {
|
||||
super(visualizer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(float zoom) {
|
||||
Levels levels = new Levels(applet.getCache().getSettings().generator);
|
||||
int worldHeight = applet.getCache().getSettings().generator.world.worldHeight;
|
||||
int waterLevel = levels.waterY;
|
||||
int resolution = applet.getCache().getRegion().getBlockSize().size;
|
||||
int center = resolution / 2;
|
||||
|
||||
float w = applet.width / (float) resolution;
|
||||
float h = applet.width / (float) resolution;
|
||||
float el = w / zoom;
|
||||
|
||||
applet.pushMatrix();
|
||||
applet.translate(-applet.width / 2F, -applet.width / 2F);
|
||||
|
||||
int difX = Math.max(0, applet.getCache().getRegion().getBlockSize().size - resolution);
|
||||
int difY = Math.max(0, applet.getCache().getRegion().getBlockSize().size - resolution);
|
||||
int offsetX = difX / 2;
|
||||
int offsetZ = difY / 2;
|
||||
|
||||
for (int dy = 0; dy < resolution; dy++) {
|
||||
for (int dx = 0; dx < resolution; dx++) {
|
||||
Cell<Terrain> cell = applet.getCache().getRegion().getCell(dx + offsetX, dy + offsetZ);
|
||||
|
||||
float cellHeight = cell.value * worldHeight;
|
||||
int height = Math.min(worldHeight, Math.max(0, (int) cellHeight));
|
||||
|
||||
if (height < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float x0 = dx * w;
|
||||
float x1 = (dx + 1) * w;
|
||||
float z0 = dy * h;
|
||||
float z1 = (dy + 1) * h;
|
||||
float y = getSurface(cell, height, waterLevel, el);
|
||||
|
||||
if ((dx == center && (dy == center || dy - 1 == center || dy + 1 == center))
|
||||
|| (dy == center && (dx - 1 == center || dx + 1 == center))) {
|
||||
applet.fill(100F, 100F, 100F);
|
||||
}
|
||||
|
||||
drawColumn(x0, z0, 0, x1, z1, y);
|
||||
}
|
||||
}
|
||||
|
||||
drawRulers(16, worldHeight, resolution, h, el);
|
||||
|
||||
applet.popMatrix();
|
||||
}
|
||||
|
||||
private void drawRulers(int step, int max, int resolution, float unit, float height) {
|
||||
float width = (resolution + 1) * unit;
|
||||
int doubleStep = step * 2;
|
||||
|
||||
for (int dz = 0; dz <= 1; dz++) {
|
||||
for (int dx = 0; dx <= 1; dx++) {
|
||||
float x0 = dx * width;
|
||||
float x1 = x0 - unit;
|
||||
float z0 = dz * width;
|
||||
float z1 = z0 - unit;
|
||||
for (int dy = 0; dy < max; dy += step) {
|
||||
float y0 = dy * height;
|
||||
float y1 = y0 + (step * height);
|
||||
float h = 100, s = 100, b = 100;
|
||||
if ((dy % doubleStep) != step) {
|
||||
s = 0;
|
||||
}
|
||||
applet.fill(h, s, b);
|
||||
drawColumn(x0, z0, y0, x1, z1, y1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void drawColumn(float x0, float y0, float z0, float x1, float y1, float z1) {
|
||||
applet.beginShape(PApplet.QUADS);
|
||||
// +Z "front" face
|
||||
applet.vertex(x0, y0, z1);
|
||||
applet.vertex(x1, y0, z1);
|
||||
applet.vertex(x1, y1, z1);
|
||||
applet.vertex(x0, y1, z1);
|
||||
|
||||
// -Z "back" face
|
||||
applet.vertex(x1, y0, z0);
|
||||
applet.vertex(x0, y0, z0);
|
||||
applet.vertex(x0, y1, z0);
|
||||
applet.vertex(x1, y1, z0);
|
||||
|
||||
// +Y "bottom" face
|
||||
applet.vertex(x0, y1, z1);
|
||||
applet.vertex(x1, y1, z1);
|
||||
applet.vertex(x1, y1, z0);
|
||||
applet.vertex(x0, y1, z0);
|
||||
|
||||
// -Y "top" face
|
||||
applet.vertex(x0, y0, z0);
|
||||
applet.vertex(x1, y0, z0);
|
||||
applet.vertex(x1, y0, z1);
|
||||
applet.vertex(x0, y0, z1);
|
||||
|
||||
// +X "right" face
|
||||
applet.vertex(x1, y0, z1);
|
||||
applet.vertex(x1, y0, z0);
|
||||
applet.vertex(x1, y1, z0);
|
||||
applet.vertex(x1, y1, z1);
|
||||
|
||||
// -X "left" face
|
||||
applet.vertex(x0, y0, z0);
|
||||
applet.vertex(x0, y0, z1);
|
||||
applet.vertex(x0, y1, z1);
|
||||
applet.vertex(x0, y1, z0);
|
||||
|
||||
applet.endShape();
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package com.terraforged.app.util;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.terraforged.core.util.serialization.serializer.Reader;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class JsonReader implements Reader {
|
||||
|
||||
private final JsonElement element;
|
||||
|
||||
public JsonReader(JsonElement element) {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getSize() {
|
||||
if (element.isJsonObject()) {
|
||||
return element.getAsJsonObject().size();
|
||||
}
|
||||
if (element.isJsonArray()) {
|
||||
return element.getAsJsonArray().size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getChild(String key) {
|
||||
return new JsonReader(element.getAsJsonObject().get(key));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Reader getChild(int index) {
|
||||
return new JsonReader(element.getAsJsonArray().get(index));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getKeys() {
|
||||
return element.getAsJsonObject().entrySet().stream().map(Map.Entry::getKey).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getString() {
|
||||
return element.getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getBool() {
|
||||
return element.getAsBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getFloat() {
|
||||
return element.getAsFloat();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInt() {
|
||||
return element.getAsInt();
|
||||
}
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package com.terraforged.app.util;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.terraforged.core.settings.Settings;
|
||||
import com.terraforged.core.util.serialization.serializer.Deserializer;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.Reader;
|
||||
|
||||
public class Loader {
|
||||
|
||||
public static Settings load() {
|
||||
Settings settings = new Settings();
|
||||
load(settings);
|
||||
return settings;
|
||||
}
|
||||
|
||||
private static void load(Settings settings) {
|
||||
try (Reader reader = new BufferedReader(new FileReader("terraforged-generator.json"))) {
|
||||
JsonElement json = new JsonParser().parse(reader);
|
||||
new Deserializer().deserialize(new JsonReader(json), settings);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,764 +0,0 @@
|
||||
[
|
||||
{
|
||||
"id": "biomesoplenty:alps",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.1,
|
||||
"color": -2302756
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:alps_foothills",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.1,
|
||||
"color": -10461088
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:bayou",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.58000004,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:bog",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.42,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:boreal_forest",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.32,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:brushland",
|
||||
"moisture": 0.06666667,
|
||||
"temperature": 0.8,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:chaparral",
|
||||
"moisture": 0.29999998,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:cherry_blossom_grove",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:cold_desert",
|
||||
"moisture": 0.0,
|
||||
"temperature": 0.3,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:coniferous_forest",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.38,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:dead_forest",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.32,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:fir_clearing",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.38,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:floodplain",
|
||||
"moisture": 0.8,
|
||||
"temperature": 0.56,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:flower_meadow",
|
||||
"moisture": 0.46666667,
|
||||
"temperature": 0.35999998,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:grassland",
|
||||
"moisture": 0.46666667,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:gravel_beach",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.44,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:grove",
|
||||
"moisture": 0.18333334,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:highland",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:highland_moor",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:lavender_field",
|
||||
"moisture": 0.46666667,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:lush_grassland",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.58000004,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:lush_swamp",
|
||||
"moisture": 0.6666667,
|
||||
"temperature": 0.48000002,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:mangrove",
|
||||
"moisture": 0.46666667,
|
||||
"temperature": 0.524,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:maple_woods",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.3,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:marsh",
|
||||
"moisture": 0.46666667,
|
||||
"temperature": 0.45999998,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:meadow",
|
||||
"moisture": 0.46666667,
|
||||
"temperature": 0.35999998,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:mire",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.42,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:mystic_grove",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.48000002,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:oasis",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:ominous_woods",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:orchard",
|
||||
"moisture": 0.26666668,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:outback",
|
||||
"moisture": 0.033333335,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:overgrown_cliffs",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.58000004,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:pasture",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:prairie",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:pumpkin_patch",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.35999998,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:rainforest",
|
||||
"moisture": 1.0,
|
||||
"temperature": 0.54,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:redwood_forest",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.52,
|
||||
"color": -12427646
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:redwood_forest_edge",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.52,
|
||||
"color": -12427646
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:scrubland",
|
||||
"moisture": 0.06666667,
|
||||
"temperature": 0.64,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:seasonal_forest",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.35999998,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:shield",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.35999998,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:shrubland",
|
||||
"moisture": 0.033333335,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:silkglade",
|
||||
"moisture": 0.13333334,
|
||||
"temperature": 0.5,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:snowy_coniferous_forest",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.1,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:snowy_fir_clearing",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.1,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:snowy_forest",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.1,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:steppe",
|
||||
"moisture": 0.033333335,
|
||||
"temperature": 0.51,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:temperate_rainforest",
|
||||
"moisture": 0.8,
|
||||
"temperature": 0.45999998,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:temperate_rainforest_hills",
|
||||
"moisture": 0.8,
|
||||
"temperature": 0.45999998,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:tropical_rainforest",
|
||||
"moisture": 0.6666667,
|
||||
"temperature": 0.6,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:tundra",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.28,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:wasteland",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -12427646
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:wetland",
|
||||
"moisture": 0.46666667,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:white_beach",
|
||||
"moisture": 0.6666667,
|
||||
"temperature": 0.58000004,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:woodland",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "biomesoplenty:xeric_shrubland",
|
||||
"moisture": 0.06666667,
|
||||
"temperature": 0.9,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:badlands",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:badlands_plateau",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:bamboo_jungle",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.58000004,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:bamboo_jungle_hills",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.58000004,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:beach",
|
||||
"moisture": 0.26666668,
|
||||
"temperature": 0.52,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:birch_forest",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:birch_forest_hills",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:cold_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:dark_forest",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.48000002,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:dark_forest_hills",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.48000002,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:deep_cold_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:deep_frozen_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:deep_lukewarm_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:deep_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:deep_warm_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:desert",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:desert_hills",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:desert_lakes",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:eroded_badlands",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:flower_forest",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.48000002,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:forest",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.48000002,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:frozen_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.2,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:frozen_river",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.2,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:giant_spruce_taiga",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.3,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:giant_spruce_taiga_hills",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.3,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:giant_tree_taiga",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.32,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:giant_tree_taiga_hills",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.32,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:gravelly_mountains",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.28,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:ice_spikes",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.2,
|
||||
"color": -2302756
|
||||
},
|
||||
{
|
||||
"id": "minecraft:jungle",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.58000004,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:jungle_hills",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.58000004,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:lukewarm_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:modified_badlands_plateau",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:modified_gravelly_mountains",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.28,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:modified_jungle",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.58000004,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:modified_wooded_badlands_plateau",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:mountains",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.28,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:mushroom_field_shore",
|
||||
"moisture": 0.6666667,
|
||||
"temperature": 0.56,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:mushroom_fields",
|
||||
"moisture": 0.6666667,
|
||||
"temperature": 0.56,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:plains",
|
||||
"moisture": 0.26666668,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:river",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:savanna",
|
||||
"moisture": 0.0,
|
||||
"temperature": 0.68,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:savanna_plateau",
|
||||
"moisture": 0.0,
|
||||
"temperature": 0.6,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:shattered_savanna",
|
||||
"moisture": 0.0,
|
||||
"temperature": 0.64,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:shattered_savanna_plateau",
|
||||
"moisture": 0.0,
|
||||
"temperature": 0.6,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:snowy_beach",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.22,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:snowy_mountains",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.2,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:snowy_taiga",
|
||||
"moisture": 0.26666668,
|
||||
"temperature": 0.0,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:snowy_taiga_hills",
|
||||
"moisture": 0.26666668,
|
||||
"temperature": 0.0,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:snowy_taiga_mountains",
|
||||
"moisture": 0.26666668,
|
||||
"temperature": 0.0,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:snowy_tundra",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.2,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:sunflower_plains",
|
||||
"moisture": 0.26666668,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:swamp",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:swamp_hills",
|
||||
"moisture": 0.59999996,
|
||||
"temperature": 0.52,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:taiga",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.3,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:taiga_hills",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.3,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:taiga_mountains",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.3,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:tall_birch_forest",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:tall_birch_hills",
|
||||
"moisture": 0.4,
|
||||
"temperature": 0.44,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:warm_ocean",
|
||||
"moisture": 0.33333334,
|
||||
"temperature": 0.4,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:wooded_badlands_plateau",
|
||||
"moisture": 0.0,
|
||||
"temperature": 1.0,
|
||||
"color": -6034953
|
||||
},
|
||||
{
|
||||
"id": "minecraft:wooded_hills",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.48000002,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "minecraft:wooded_mountains",
|
||||
"moisture": 0.2,
|
||||
"temperature": 0.28,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "terraforged:cold_steppe",
|
||||
"moisture": 0.06666667,
|
||||
"temperature": 0.28,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "terraforged:savanna_scrub",
|
||||
"moisture": 0.0,
|
||||
"temperature": 0.68,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "terraforged:shattered_savanna_scrub",
|
||||
"moisture": 0.0,
|
||||
"temperature": 0.64,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "terraforged:snowy_taiga_scrub",
|
||||
"moisture": 0.26666668,
|
||||
"temperature": 0.0,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "terraforged:steppe",
|
||||
"moisture": 0.06666667,
|
||||
"temperature": 0.48000002,
|
||||
"color": -13592211
|
||||
},
|
||||
{
|
||||
"id": "terraforged:taiga_scrub",
|
||||
"moisture": 0.53333336,
|
||||
"temperature": 0.3,
|
||||
"color": -13592211
|
||||
}
|
||||
]
|
@ -1,168 +0,0 @@
|
||||
{
|
||||
"TROPICAL_RAINFOREST": [
|
||||
"biomesoplenty:overgrown_cliffs",
|
||||
"biomesoplenty:tropical_rainforest",
|
||||
"minecraft:bamboo_jungle",
|
||||
"minecraft:bamboo_jungle_hills",
|
||||
"minecraft:jungle",
|
||||
"minecraft:jungle_hills",
|
||||
"minecraft:modified_jungle"
|
||||
],
|
||||
"SAVANNA": [
|
||||
"biomesoplenty:brushland",
|
||||
"biomesoplenty:scrubland",
|
||||
"biomesoplenty:xeric_shrubland",
|
||||
"minecraft:savanna",
|
||||
"minecraft:savanna_plateau",
|
||||
"minecraft:shattered_savanna",
|
||||
"minecraft:shattered_savanna_plateau",
|
||||
"terraforged:savanna_scrub",
|
||||
"terraforged:shattered_savanna_scrub"
|
||||
],
|
||||
"DESERT": [
|
||||
"biomesoplenty:oasis",
|
||||
"biomesoplenty:outback",
|
||||
"biomesoplenty:wasteland",
|
||||
"minecraft:badlands",
|
||||
"minecraft:badlands_plateau",
|
||||
"minecraft:desert",
|
||||
"minecraft:desert_hills",
|
||||
"minecraft:desert_lakes",
|
||||
"minecraft:eroded_badlands",
|
||||
"minecraft:modified_badlands_plateau",
|
||||
"minecraft:modified_wooded_badlands_plateau",
|
||||
"minecraft:wooded_badlands_plateau"
|
||||
],
|
||||
"TEMPERATE_RAINFOREST": [
|
||||
"biomesoplenty:rainforest",
|
||||
"biomesoplenty:temperate_rainforest",
|
||||
"biomesoplenty:temperate_rainforest_hills",
|
||||
"minecraft:plains"
|
||||
],
|
||||
"TEMPERATE_FOREST": [
|
||||
"biomesoplenty:cherry_blossom_grove",
|
||||
"biomesoplenty:grove",
|
||||
"biomesoplenty:mystic_grove",
|
||||
"biomesoplenty:orchard",
|
||||
"biomesoplenty:pumpkin_patch",
|
||||
"biomesoplenty:redwood_forest",
|
||||
"biomesoplenty:redwood_forest_edge",
|
||||
"biomesoplenty:seasonal_forest",
|
||||
"biomesoplenty:silkglade",
|
||||
"biomesoplenty:temperate_rainforest",
|
||||
"biomesoplenty:temperate_rainforest_hills",
|
||||
"biomesoplenty:woodland",
|
||||
"minecraft:birch_forest",
|
||||
"minecraft:birch_forest_hills",
|
||||
"minecraft:dark_forest",
|
||||
"minecraft:flower_forest",
|
||||
"minecraft:forest",
|
||||
"minecraft:plains",
|
||||
"minecraft:tall_birch_forest",
|
||||
"minecraft:wooded_hills"
|
||||
],
|
||||
"GRASSLAND": [
|
||||
"biomesoplenty:bayou",
|
||||
"biomesoplenty:bog",
|
||||
"biomesoplenty:chaparral",
|
||||
"biomesoplenty:floodplain",
|
||||
"biomesoplenty:grassland",
|
||||
"biomesoplenty:highland_moor",
|
||||
"biomesoplenty:lavender_field",
|
||||
"biomesoplenty:lush_grassland",
|
||||
"biomesoplenty:lush_swamp",
|
||||
"biomesoplenty:mangrove",
|
||||
"biomesoplenty:marsh",
|
||||
"biomesoplenty:mire",
|
||||
"biomesoplenty:pasture",
|
||||
"biomesoplenty:prairie",
|
||||
"biomesoplenty:shrubland",
|
||||
"biomesoplenty:steppe",
|
||||
"biomesoplenty:wetland",
|
||||
"minecraft:plains",
|
||||
"minecraft:sunflower_plains",
|
||||
"minecraft:swamp"
|
||||
],
|
||||
"COLD_STEPPE": [
|
||||
"terraforged:cold_steppe"
|
||||
],
|
||||
"STEPPE": [
|
||||
"biomesoplenty:steppe",
|
||||
"terraforged:steppe"
|
||||
],
|
||||
"TAIGA": [
|
||||
"biomesoplenty:boreal_forest",
|
||||
"biomesoplenty:coniferous_forest",
|
||||
"biomesoplenty:dead_forest",
|
||||
"biomesoplenty:fir_clearing",
|
||||
"biomesoplenty:flower_meadow",
|
||||
"biomesoplenty:maple_woods",
|
||||
"biomesoplenty:meadow",
|
||||
"biomesoplenty:ominous_woods",
|
||||
"biomesoplenty:shield",
|
||||
"biomesoplenty:tundra",
|
||||
"minecraft:giant_spruce_taiga",
|
||||
"minecraft:giant_tree_taiga",
|
||||
"minecraft:giant_tree_taiga_hills",
|
||||
"minecraft:taiga",
|
||||
"minecraft:taiga_hills",
|
||||
"terraforged:taiga_scrub"
|
||||
],
|
||||
"TUNDRA": [
|
||||
"biomesoplenty:alps",
|
||||
"biomesoplenty:alps_foothills",
|
||||
"biomesoplenty:snowy_coniferous_forest",
|
||||
"biomesoplenty:snowy_fir_clearing",
|
||||
"biomesoplenty:snowy_forest",
|
||||
"minecraft:ice_spikes",
|
||||
"minecraft:snowy_taiga",
|
||||
"minecraft:snowy_taiga_hills",
|
||||
"minecraft:snowy_tundra",
|
||||
"terraforged:snowy_taiga_scrub"
|
||||
],
|
||||
"ALPINE": [
|
||||
"biomesoplenty:highland",
|
||||
"minecraft:gravelly_mountains",
|
||||
"minecraft:modified_gravelly_mountains",
|
||||
"minecraft:mountains",
|
||||
"minecraft:snowy_mountains",
|
||||
"minecraft:snowy_taiga_mountains",
|
||||
"minecraft:taiga_mountains",
|
||||
"minecraft:wooded_mountains"
|
||||
],
|
||||
"rivers": {
|
||||
"COLD": [
|
||||
"minecraft:frozen_river"
|
||||
],
|
||||
"MEDIUM": [
|
||||
"minecraft:river"
|
||||
],
|
||||
"WARM": []
|
||||
},
|
||||
"oceans": {
|
||||
"COLD": [
|
||||
"minecraft:cold_ocean",
|
||||
"minecraft:frozen_ocean"
|
||||
],
|
||||
"MEDIUM": [
|
||||
"minecraft:ocean"
|
||||
],
|
||||
"WARM": [
|
||||
"minecraft:lukewarm_ocean",
|
||||
"minecraft:warm_ocean"
|
||||
]
|
||||
},
|
||||
"deep_oceans": {
|
||||
"COLD": [
|
||||
"minecraft:deep_cold_ocean",
|
||||
"minecraft:deep_frozen_ocean"
|
||||
],
|
||||
"MEDIUM": [
|
||||
"minecraft:deep_ocean"
|
||||
],
|
||||
"WARM": [
|
||||
"minecraft:deep_lukewarm_ocean",
|
||||
"minecraft:deep_warm_ocean"
|
||||
]
|
||||
}
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 7.0 KiB |
@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 TerraForged
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
@ -1,31 +0,0 @@
|
||||
apply plugin: "maven-publish"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile project(":Noise2D")
|
||||
compile "it.unimi.dsi:fastutil:8.2.1"
|
||||
}
|
||||
|
||||
publishing {
|
||||
publications {
|
||||
mavenJava(MavenPublication) {
|
||||
artifact jar
|
||||
}
|
||||
}
|
||||
|
||||
if (System.getenv("MAVEN_USER") != null && System.getenv("MAVEN_PASS") != null) {
|
||||
repositories {
|
||||
maven {
|
||||
credentials {
|
||||
username System.getenv("MAVEN_USER")
|
||||
password System.getenv("MAVEN_PASS")
|
||||
}
|
||||
name = "nexus"
|
||||
url = "https://io.terraforged.com/repository/maven/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.cell;
|
||||
|
||||
import com.terraforged.core.util.concurrent.ObjectPool;
|
||||
import com.terraforged.core.world.biome.BiomeType;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
public class Cell<T extends Tag> {
|
||||
|
||||
private static final Cell EMPTY = new Cell() {
|
||||
@Override
|
||||
public boolean isAbsent() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
private static final ObjectPool<Cell<Terrain>> POOL = new ObjectPool<>(100, Cell::new);
|
||||
|
||||
public float continent;
|
||||
public float continentEdge;
|
||||
public float region;
|
||||
public float regionEdge;
|
||||
public float biome;
|
||||
public float biomeEdge = 1F;
|
||||
public float riverMask = 1F;
|
||||
|
||||
public float value;
|
||||
public float biomeMoisture;
|
||||
public float biomeTemperature;
|
||||
public float moisture;
|
||||
public float temperature;
|
||||
public float steepness;
|
||||
public float erosion;
|
||||
public float sediment;
|
||||
public float biomeTypeMask = 1F;
|
||||
public BiomeType biomeType = BiomeType.GRASSLAND;
|
||||
|
||||
public T tag = null;
|
||||
|
||||
public void copy(Cell<T> other) {
|
||||
value = other.value;
|
||||
|
||||
continent = other.continent;
|
||||
continentEdge = other.continentEdge;
|
||||
|
||||
region = other.region;
|
||||
regionEdge = other.regionEdge;
|
||||
|
||||
biome = other.biome;
|
||||
biomeEdge = other.biomeEdge;
|
||||
|
||||
riverMask = other.riverMask;
|
||||
|
||||
moisture = other.moisture;
|
||||
temperature = other.temperature;
|
||||
biomeMoisture = other.biomeMoisture;
|
||||
biomeTemperature = other.biomeTemperature;
|
||||
|
||||
steepness = other.steepness;
|
||||
erosion = other.erosion;
|
||||
sediment = other.sediment;
|
||||
biomeType = other.biomeType;
|
||||
biomeTypeMask = other.biomeTypeMask;
|
||||
|
||||
tag = other.tag;
|
||||
}
|
||||
|
||||
public float continentMask(float min, float max) {
|
||||
return NoiseUtil.map(continentEdge, min, max, max - min);
|
||||
}
|
||||
|
||||
public float regionMask(float min, float max) {
|
||||
return NoiseUtil.map(regionEdge, min, max, max - min);
|
||||
}
|
||||
|
||||
public float biomeMask(float min, float max) {
|
||||
return NoiseUtil.map(biomeEdge, min, max, max - min);
|
||||
}
|
||||
|
||||
public float mask(float cmin, float cmax, float rmin, float rmax) {
|
||||
return riverMask * continentMask(cmin, cmax) * regionMask(rmin, rmax);
|
||||
}
|
||||
|
||||
public boolean isAbsent() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Tag> Cell<T> empty() {
|
||||
return EMPTY;
|
||||
}
|
||||
|
||||
public static ObjectPool.Item<Cell<Terrain>> pooled() {
|
||||
return POOL.get();
|
||||
}
|
||||
|
||||
public interface Visitor<T extends Tag> {
|
||||
|
||||
void visit(Cell<T> cell, int dx, int dz);
|
||||
}
|
||||
|
||||
public interface ContextVisitor<C, T extends Tag> {
|
||||
|
||||
void visit(Cell<T> cell, int dx, int dz, C ctx);
|
||||
}
|
||||
|
||||
public interface ZoomVisitor<T extends Tag> {
|
||||
|
||||
void visit(Cell<T> cell, float x, float z);
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.cell;
|
||||
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
|
||||
public interface Extent {
|
||||
|
||||
void visit(int minX, int minZ, int maxX, int maxZ, Cell.Visitor<Terrain> visitor);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.cell;
|
||||
|
||||
import com.terraforged.core.util.concurrent.ObjectPool;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.Module;
|
||||
|
||||
public interface Populator extends Module {
|
||||
|
||||
void apply(Cell<Terrain> cell, float x, float y);
|
||||
|
||||
void tag(Cell<Terrain> cell, float x, float y);
|
||||
|
||||
@Override
|
||||
default float getValue(float x, float z) {
|
||||
try (ObjectPool.Item<Cell<Terrain>> cell = Cell.pooled()) {
|
||||
apply(cell.getValue(), x, z);
|
||||
return cell.getValue().value;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.cell;
|
||||
|
||||
public interface Tag {
|
||||
|
||||
String getName();
|
||||
}
|
@ -1,291 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.filter;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.region.Size;
|
||||
import com.terraforged.core.settings.Settings;
|
||||
import com.terraforged.core.world.heightmap.Levels;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
/*
|
||||
* This class in an adaption of the work by Sebastian Lague which is also licensed under MIT.
|
||||
* Reference:
|
||||
* https://github.com/SebLague/Hydraulic-Erosion/blob/Coding-Adventure-E01/Assets/Scripts/Erosion.cs
|
||||
* https://github.com/SebLague/Hydraulic-Erosion/blob/Coding-Adventure-E01/LICENSE
|
||||
*
|
||||
* License In Full:
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2019 Sebastian Lague
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
public class Erosion implements Filter {
|
||||
|
||||
private int erosionRadius = 3;
|
||||
private float inertia = 0.05f;
|
||||
private float sedimentCapacityFactor = 4;
|
||||
private float minSedimentCapacity = 0.01f;
|
||||
private float erodeSpeed = 0.3f;
|
||||
private float depositSpeed = 0.3f;
|
||||
private float evaporateSpeed = 0.01f;
|
||||
private float gravity = 8;
|
||||
private int maxDropletLifetime = 30;
|
||||
private float initialWaterVolume = 1;
|
||||
private float initialSpeed = 1;
|
||||
private final TerrainPos gradient = new TerrainPos();
|
||||
private int[][] erosionBrushIndices = new int[0][];
|
||||
private float[][] erosionBrushWeights = new float[0][];
|
||||
|
||||
private final Modifier modifier;
|
||||
private final Random random = new Random();
|
||||
|
||||
public Erosion(Settings settings, Levels levels) {
|
||||
erodeSpeed = settings.filters.erosion.erosionRate;
|
||||
depositSpeed = settings.filters.erosion.depositeRate;
|
||||
modifier = Modifier.range(levels.ground, levels.ground(15));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Filterable<?> map, int seedX, int seedZ, int iterations) {
|
||||
if (erosionBrushIndices.length != map.getSize().total) {
|
||||
init(map.getSize().total, erosionRadius);
|
||||
}
|
||||
|
||||
applyMain(map, seedX, seedZ, iterations, random);
|
||||
|
||||
// applyNeighbours(map, seedX, seedZ, iterations, random);
|
||||
}
|
||||
|
||||
private int nextCoord(Size size, Random random) {
|
||||
return random.nextInt(size.total - 1);
|
||||
}
|
||||
|
||||
private void applyMain(Filterable<?> map, int seedX, int seedZ, int iterations, Random random) {
|
||||
random.setSeed(NoiseUtil.seed(seedX, seedZ));
|
||||
while (iterations-- > 0) {
|
||||
int posX = nextCoord(map.getSize(), random);
|
||||
int posZ = nextCoord(map.getSize(), random);
|
||||
apply(map.getBacking(), posX, posZ, map.getSize().total);
|
||||
}
|
||||
}
|
||||
|
||||
private void apply(Cell<?>[] cells, float posX, float posY, int size) {
|
||||
float dirX = 0;
|
||||
float dirY = 0;
|
||||
float speed = initialSpeed;
|
||||
float water = initialWaterVolume;
|
||||
float sediment = 0;
|
||||
|
||||
for (int lifetime = 0; lifetime < maxDropletLifetime; lifetime++) {
|
||||
int nodeX = (int) posX;
|
||||
int nodeY = (int) posY;
|
||||
int dropletIndex = nodeY * size + nodeX;
|
||||
// Calculate droplet's offset inside the cell (0,0) = at NW node, (1,1) = at SE node
|
||||
float cellOffsetX = posX - nodeX;
|
||||
float cellOffsetY = posY - nodeY;
|
||||
|
||||
// Calculate droplet's height and direction of flow with bilinear interpolation of surrounding heights
|
||||
gradient.update(cells, size, posX, posY);
|
||||
|
||||
// Update the droplet's direction and position (move position 1 unit regardless of speed)
|
||||
dirX = (dirX * inertia - gradient.gradientX * (1 - inertia));
|
||||
dirY = (dirY * inertia - gradient.gradientY * (1 - inertia));
|
||||
|
||||
// Normalize direction
|
||||
float len = (float) Math.sqrt(dirX * dirX + dirY * dirY);
|
||||
if (Float.isNaN(len)) {
|
||||
len = 0;
|
||||
}
|
||||
|
||||
if (len != 0) {
|
||||
dirX /= len;
|
||||
dirY /= len;
|
||||
}
|
||||
|
||||
posX += dirX;
|
||||
posY += dirY;
|
||||
|
||||
// Stop simulating droplet if it's not moving or has flowed over edge of map
|
||||
if ((dirX == 0 && dirY == 0) || posX < 0 || posX >= size - 1 || posY < 0 || posY >= size - 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Find the droplet's new height and calculate the deltaHeight
|
||||
float oldHeight = gradient.height;
|
||||
float newHeight = gradient.update(cells, size, posX, posY).height;
|
||||
float deltaHeight = newHeight - oldHeight;
|
||||
|
||||
// Calculate the droplet's sediment capacity (higher when moving fast down a slope and contains lots of water)
|
||||
float sedimentCapacity = Math.max(-deltaHeight * speed * water * sedimentCapacityFactor, minSedimentCapacity);
|
||||
|
||||
// If carrying more sediment than capacity, or if flowing uphill:
|
||||
if (sediment > sedimentCapacity || deltaHeight > 0) {
|
||||
// If moving uphill (deltaHeight > 0) try fill up to the current height, otherwise deposit a fraction of the excess sediment
|
||||
float amountToDeposit = (deltaHeight > 0) ? Math.min(deltaHeight, sediment) : (sediment - sedimentCapacity) * depositSpeed;
|
||||
sediment -= amountToDeposit;
|
||||
|
||||
// Add the sediment to the four nodes of the current cell using bilinear interpolation
|
||||
// Deposition is not distributed over a radius (like erosion) so that it can fill small pits
|
||||
deposit(cells[dropletIndex], amountToDeposit * (1 - cellOffsetX) * (1 - cellOffsetY));
|
||||
deposit(cells[dropletIndex + 1], amountToDeposit * cellOffsetX * (1 - cellOffsetY));
|
||||
deposit(cells[dropletIndex + size], amountToDeposit * (1 - cellOffsetX) * cellOffsetY);
|
||||
deposit(cells[dropletIndex + size + 1], amountToDeposit * cellOffsetX * cellOffsetY);
|
||||
} else {
|
||||
// Erode a fraction of the droplet's current carry capacity.
|
||||
// Clamp the erosion to the change in height so that it doesn't dig a hole in the terrain behind the droplet
|
||||
float amountToErode = Math.min((sedimentCapacity - sediment) * erodeSpeed, -deltaHeight);
|
||||
|
||||
// Use erosion brush to erode from all nodes inside the droplet's erosion radius
|
||||
for (int brushPointIndex = 0; brushPointIndex < erosionBrushIndices[dropletIndex].length; brushPointIndex++) {
|
||||
int nodeIndex = erosionBrushIndices[dropletIndex][brushPointIndex];
|
||||
Cell<?> cell = cells[nodeIndex];
|
||||
float brushWeight = erosionBrushWeights[dropletIndex][brushPointIndex];
|
||||
float weighedErodeAmount = amountToErode * brushWeight;
|
||||
float deltaSediment = Math.min(cell.value, weighedErodeAmount);//cell.value < weighedErodeAmount) ? cell.value : weighedErodeAmount;
|
||||
erode(cell, deltaSediment);
|
||||
sediment += deltaSediment;
|
||||
}
|
||||
}
|
||||
|
||||
// Update droplet's speed and water content
|
||||
speed = (float) Math.sqrt(speed * speed + deltaHeight * gravity);
|
||||
water *= (1 - evaporateSpeed);
|
||||
|
||||
if (Float.isNaN(speed)) {
|
||||
speed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void init(int size, int radius) {
|
||||
erosionBrushIndices = new int[size * size][];
|
||||
erosionBrushWeights = new float[size * size][];
|
||||
|
||||
int[] xOffsets = new int[radius * radius * 4];
|
||||
int[] yOffsets = new int[radius * radius * 4];
|
||||
float[] weights = new float[radius * radius * 4];
|
||||
float weightSum = 0;
|
||||
int addIndex = 0;
|
||||
|
||||
for (int i = 0; i < erosionBrushIndices.length; i++) {
|
||||
int centreX = i % size;
|
||||
int centreY = i / size;
|
||||
|
||||
if (centreY <= radius || centreY >= size - radius || centreX <= radius + 1 || centreX >= size - radius) {
|
||||
weightSum = 0;
|
||||
addIndex = 0;
|
||||
for (int y = -radius; y <= radius; y++) {
|
||||
for (int x = -radius; x <= radius; x++) {
|
||||
float sqrDst = x * x + y * y;
|
||||
if (sqrDst < radius * radius) {
|
||||
int coordX = centreX + x;
|
||||
int coordY = centreY + y;
|
||||
|
||||
if (coordX >= 0 && coordX < size && coordY >= 0 && coordY < size) {
|
||||
float weight = 1 - (float) Math.sqrt(sqrDst) / radius;
|
||||
weightSum += weight;
|
||||
weights[addIndex] = weight;
|
||||
xOffsets[addIndex] = x;
|
||||
yOffsets[addIndex] = y;
|
||||
addIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int numEntries = addIndex;
|
||||
erosionBrushIndices[i] = new int[numEntries];
|
||||
erosionBrushWeights[i] = new float[numEntries];
|
||||
|
||||
for (int j = 0; j < numEntries; j++) {
|
||||
erosionBrushIndices[i][j] = (yOffsets[j] + centreY) * size + xOffsets[j] + centreX;
|
||||
erosionBrushWeights[i][j] = weights[j] / weightSum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void deposit(Cell<?> cell, float amount) {
|
||||
float change = modifier.modify(cell, amount);
|
||||
cell.value += change;
|
||||
cell.sediment += change;
|
||||
}
|
||||
|
||||
private void erode(Cell<?> cell, float amount) {
|
||||
float change = modifier.modify(cell, amount);
|
||||
cell.value -= change;
|
||||
cell.erosion -= change;
|
||||
}
|
||||
|
||||
private static class TerrainPos {
|
||||
private float height;
|
||||
private float gradientX;
|
||||
private float gradientY;
|
||||
|
||||
private TerrainPos update(Cell<?>[] nodes, int mapSize, float posX, float posY) {
|
||||
int coordX = (int) posX;
|
||||
int coordY = (int) posY;
|
||||
|
||||
// Calculate droplet's offset inside the cell (0,0) = at NW node, (1,1) = at SE node
|
||||
float x = posX - coordX;
|
||||
float y = posY - coordY;
|
||||
|
||||
// Calculate heights of the four nodes of the droplet's cell
|
||||
int nodeIndexNW = coordY * mapSize + coordX;
|
||||
float heightNW = nodes[nodeIndexNW].value;
|
||||
float heightNE = nodes[nodeIndexNW + 1].value;
|
||||
float heightSW = nodes[nodeIndexNW + mapSize].value;
|
||||
float heightSE = nodes[nodeIndexNW + mapSize + 1].value;
|
||||
|
||||
// Calculate droplet's direction of flow with bilinear interpolation of height difference along the edges
|
||||
this.gradientX = (heightNE - heightNW) * (1 - y) + (heightSE - heightSW) * y;
|
||||
this.gradientY = (heightSW - heightNW) * (1 - x) + (heightSE - heightNE) * x;
|
||||
// Calculate height with bilinear interpolation of the heights of the nodes of the cell
|
||||
this.height = heightNW * (1 - x) * (1 - y) + heightNE * x * (1 - y) + heightSW * (1 - x) * y + heightSE * x * y;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.filter;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
|
||||
public interface Filter {
|
||||
|
||||
void apply(Filterable<?> map, int seedX, int seedZ, int iterations);
|
||||
|
||||
default void iterate(Filterable<?> map, Visitor visitor) {
|
||||
for (int dz = 0; dz < map.getSize().total; dz++) {
|
||||
for (int dx = 0; dx < map.getSize().total; dx++) {
|
||||
Cell<?> cell = map.getCellRaw(dx, dz);
|
||||
visitor.visit(map, cell, dx, dz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Visitor {
|
||||
|
||||
void visit(Filterable<?> cellMap, Cell cell, int dx, int dz);
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.filter;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.cell.Tag;
|
||||
import com.terraforged.core.region.Size;
|
||||
|
||||
public interface Filterable<T extends Tag> {
|
||||
|
||||
Size getSize();
|
||||
|
||||
Cell<T>[] getBacking();
|
||||
|
||||
Cell<T> getCellRaw(int x, int z);
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.filter;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
|
||||
public interface Modifier {
|
||||
|
||||
float getModifier(float value);
|
||||
|
||||
default float modify(Cell cell, float value) {
|
||||
return value * getModifier(cell.value);
|
||||
}
|
||||
|
||||
default Modifier invert() {
|
||||
return v -> 1 - getModifier(v);
|
||||
}
|
||||
|
||||
static Modifier range(float minValue, float maxValue) {
|
||||
return new Modifier() {
|
||||
|
||||
private final float min = minValue;
|
||||
private final float max = maxValue;
|
||||
private final float range = maxValue - minValue;
|
||||
|
||||
@Override
|
||||
public float getModifier(float value) {
|
||||
if (value > max) {
|
||||
return 1F;
|
||||
}
|
||||
if (value < min) {
|
||||
return 0F;
|
||||
}
|
||||
return (value - min) / range;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.filter;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.settings.Settings;
|
||||
import com.terraforged.core.world.heightmap.Levels;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
public class Smoothing implements Filter {
|
||||
|
||||
private final int radius;
|
||||
private final float rad2;
|
||||
private final float strength;
|
||||
private final Modifier modifier;
|
||||
|
||||
public Smoothing(Settings settings, Levels levels) {
|
||||
this.radius = NoiseUtil.round(settings.filters.smoothing.smoothingRadius + 0.5F);
|
||||
this.rad2 = settings.filters.smoothing.smoothingRadius * settings.filters.smoothing.smoothingRadius;
|
||||
this.strength = settings.filters.smoothing.smoothingRate;
|
||||
this.modifier = Modifier.range(levels.ground(1), levels.ground(120)).invert();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Filterable<?> map, int seedX, int seedZ, int iterations) {
|
||||
while (iterations-- > 0) {
|
||||
apply(map);
|
||||
}
|
||||
}
|
||||
|
||||
private void apply(Filterable<?> cellMap) {
|
||||
int maxZ = cellMap.getSize().total - radius;
|
||||
int maxX = cellMap.getSize().total - radius;
|
||||
for (int z = radius; z < maxZ; z++) {
|
||||
for (int x = radius; x < maxX; x++) {
|
||||
Cell<?> cell = cellMap.getCellRaw(x, z);
|
||||
|
||||
float total = 0;
|
||||
float weights = 0;
|
||||
|
||||
for (int dz = -radius; dz <= radius; dz++) {
|
||||
for (int dx = -radius; dx <= radius; dx++) {
|
||||
float dist2 = dx * dx + dz * dz;
|
||||
if (dist2 > rad2) {
|
||||
continue;
|
||||
}
|
||||
int px = x + dx;
|
||||
int pz = z + dz;
|
||||
Cell<?> neighbour = cellMap.getCellRaw(px, pz);
|
||||
if (neighbour.isAbsent()) {
|
||||
continue;
|
||||
}
|
||||
float value = neighbour.value;
|
||||
float weight = 1F - (dist2 / rad2);
|
||||
total += (value * weight);
|
||||
weights += weight;
|
||||
}
|
||||
}
|
||||
|
||||
if (weights > 0) {
|
||||
float dif = cell.value - (total / weights);
|
||||
cell.value -= modifier.modify(cell, dif * strength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.filter;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.heightmap.Levels;
|
||||
import com.terraforged.core.world.terrain.Terrains;
|
||||
|
||||
public class Steepness implements Filter, Filter.Visitor {
|
||||
|
||||
private final int radius;
|
||||
private final float scaler;
|
||||
private final float waterLevel;
|
||||
private final float maxBeachLevel;
|
||||
private final Terrains terrains;
|
||||
|
||||
public Steepness(int radius, float scaler, Terrains terrains, Levels levels) {
|
||||
this.radius = radius;
|
||||
this.scaler = scaler;
|
||||
this.terrains = terrains;
|
||||
this.waterLevel = levels.water;
|
||||
this.maxBeachLevel = levels.water(6);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Filterable<?> cellMap, int seedX, int seedZ, int iterations) {
|
||||
iterate(cellMap, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(Filterable<?> cellMap, Cell cell, int cx, int cz) {
|
||||
float totalHeightDif = 0F;
|
||||
for (int dz = -1; dz <= 2; dz++) {
|
||||
for (int dx = -1; dx <= 2; dx++) {
|
||||
if (dx == 0 && dz == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int x = cx + dx * radius;
|
||||
int z = cz + dz * radius;
|
||||
Cell<?> neighbour = cellMap.getCellRaw(x, z);
|
||||
if (neighbour.isAbsent()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float height = Math.max(neighbour.value, waterLevel);
|
||||
|
||||
totalHeightDif += (Math.abs(cell.value - height) / radius);
|
||||
}
|
||||
}
|
||||
cell.steepness = Math.min(1, totalHeightDif * scaler);
|
||||
if (cell.tag == terrains.coast && cell.steepness < 0.225F && cell.value < maxBeachLevel) {
|
||||
cell.tag = terrains.beach;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.module;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.cell.Populator;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.func.Interpolation;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
public class Blender extends Select implements Populator {
|
||||
|
||||
private final Populator lower;
|
||||
private final Populator upper;
|
||||
|
||||
private final float blendLower;
|
||||
private final float blendUpper;
|
||||
private final float blendRange;
|
||||
private final float midpoint;
|
||||
private final float tagThreshold;
|
||||
|
||||
public Blender(Module control, Populator lower, Populator upper, float min, float max, float split) {
|
||||
super(control);
|
||||
this.lower = lower;
|
||||
this.upper = upper;
|
||||
this.blendLower = min;
|
||||
this.blendUpper = max;
|
||||
this.blendRange = blendUpper - blendLower;
|
||||
this.midpoint = blendLower + (blendRange * split);
|
||||
this.tagThreshold = midpoint;
|
||||
}
|
||||
|
||||
public Blender(Populator control, Populator lower, Populator upper, float min, float max, float split, float tagThreshold) {
|
||||
super(control);
|
||||
this.lower = lower;
|
||||
this.upper = upper;
|
||||
this.blendLower = min;
|
||||
this.blendUpper = max;
|
||||
this.blendRange = blendUpper - blendLower;
|
||||
this.midpoint = blendLower + (blendRange * split);
|
||||
this.tagThreshold = tagThreshold;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Cell<Terrain> cell, float x, float y) {
|
||||
float select = getSelect(cell, x, y);
|
||||
|
||||
if (select < blendLower) {
|
||||
lower.apply(cell, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (select > blendUpper) {
|
||||
upper.apply(cell, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
float alpha = Interpolation.LINEAR.apply((select - blendLower) / blendRange);
|
||||
lower.apply(cell, x, y);
|
||||
|
||||
float lowerVal = cell.value;
|
||||
Terrain lowerType = cell.tag;
|
||||
|
||||
upper.apply(cell, x, y);
|
||||
float upperVal = cell.value;
|
||||
|
||||
cell.value = NoiseUtil.lerp(lowerVal, upperVal, alpha);
|
||||
if (select < midpoint) {
|
||||
cell.tag = lowerType;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tag(Cell<Terrain> cell, float x, float y) {
|
||||
float select = getSelect(cell, x, y);
|
||||
if (select < blendLower) {
|
||||
lower.tag(cell, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (select > blendUpper) {
|
||||
upper.tag(cell, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (select < tagThreshold) {
|
||||
lower.tag(cell, x, y);
|
||||
} else {
|
||||
upper.tag(cell, x, y);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,122 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.module;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.cell.Populator;
|
||||
import com.terraforged.core.world.climate.Climate;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.func.Interpolation;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
public class MultiBlender extends Select implements Populator {
|
||||
|
||||
private final Climate climate;
|
||||
private final Populator lower;
|
||||
private final Populator middle;
|
||||
private final Populator upper;
|
||||
private final float midpoint;
|
||||
|
||||
private final float blendLower;
|
||||
private final float blendUpper;
|
||||
|
||||
private final float lowerRange;
|
||||
private final float upperRange;
|
||||
|
||||
public MultiBlender(Climate climate, Populator control, Populator lower, Populator middle, Populator upper, float min, float mid, float max) {
|
||||
super(control);
|
||||
this.climate = climate;
|
||||
this.lower = lower;
|
||||
this.upper = upper;
|
||||
this.middle = middle;
|
||||
|
||||
this.midpoint = mid;
|
||||
this.blendLower = min;
|
||||
this.blendUpper = max;
|
||||
|
||||
this.lowerRange = midpoint - blendLower;
|
||||
this.upperRange = blendUpper - midpoint;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Cell<Terrain> cell, float x, float y) {
|
||||
float select = getSelect(cell, x, y);
|
||||
if (select < blendLower) {
|
||||
lower.apply(cell, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (select > blendUpper) {
|
||||
upper.apply(cell, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (select < midpoint) {
|
||||
float alpha = Interpolation.CURVE3.apply((select - blendLower) / lowerRange);
|
||||
|
||||
lower.apply(cell, x, y);
|
||||
float lowerVal = cell.value;
|
||||
Terrain lowerType = cell.tag;
|
||||
|
||||
middle.apply(cell, x, y);
|
||||
float upperVal = cell.value;
|
||||
|
||||
cell.value = NoiseUtil.lerp(lowerVal, upperVal, alpha);
|
||||
} else {
|
||||
float alpha = Interpolation.CURVE3.apply((select - midpoint) / upperRange);
|
||||
|
||||
middle.apply(cell, x, y);
|
||||
float lowerVal = cell.value;
|
||||
|
||||
upper.apply(cell, x, y);
|
||||
cell.value = NoiseUtil.lerp(lowerVal, cell.value, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tag(Cell<Terrain> cell, float x, float y) {
|
||||
float select = getSelect(cell, x, y);
|
||||
if (select < blendLower) {
|
||||
lower.tag(cell, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (select > blendUpper) {
|
||||
upper.tag(cell, x, y);
|
||||
return;
|
||||
}
|
||||
|
||||
if (select < midpoint) {
|
||||
lower.tag(cell, x, y);
|
||||
// upper.tag(cell, x, y);
|
||||
if (cell.value > cell.tag.getMax(climate.getRand().getValue(x, y))) {
|
||||
upper.tag(cell, x, y);
|
||||
}
|
||||
} else {
|
||||
upper.tag(cell, x, y);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.module;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.Module;
|
||||
|
||||
public class Select {
|
||||
|
||||
private final Module control;
|
||||
|
||||
public Select(Module control) {
|
||||
this.control = control;
|
||||
}
|
||||
|
||||
public float getSelect(Cell<Terrain> cell, float x, float y) {
|
||||
return control.getValue(x, y);
|
||||
}
|
||||
}
|
@ -1,404 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.cell.Extent;
|
||||
import com.terraforged.core.filter.Filterable;
|
||||
import com.terraforged.core.region.chunk.ChunkReader;
|
||||
import com.terraforged.core.region.chunk.ChunkWriter;
|
||||
import com.terraforged.core.util.concurrent.Disposable;
|
||||
import com.terraforged.core.world.decorator.Decorator;
|
||||
import com.terraforged.core.world.heightmap.Heightmap;
|
||||
import com.terraforged.core.world.rivermap.RiverRegionList;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class Region implements Extent, Disposable {
|
||||
|
||||
private final int regionX;
|
||||
private final int regionZ;
|
||||
private final int chunkX;
|
||||
private final int chunkZ;
|
||||
private final int blockX;
|
||||
private final int blockZ;
|
||||
private final int border;
|
||||
private final Size blockSize;
|
||||
private final Size chunkSize;
|
||||
private final GenCell[] blocks;
|
||||
private final GenChunk[] chunks;
|
||||
private final int disposableChunks;
|
||||
private final Disposable.Listener<Region> disposalListener;
|
||||
private final AtomicInteger disposedChunks = new AtomicInteger();
|
||||
|
||||
public Region(int regionX, int regionZ, int size, int borderChunks) {
|
||||
this(regionX, regionZ, size, borderChunks, region -> {});
|
||||
}
|
||||
|
||||
public Region(int regionX, int regionZ, int size, int borderChunks, Disposable.Listener<Region> disposalListener) {
|
||||
this.regionX = regionX;
|
||||
this.regionZ = regionZ;
|
||||
this.chunkX = regionX << size;
|
||||
this.chunkZ = regionZ << size;
|
||||
this.blockX = Size.chunkToBlock(chunkX);
|
||||
this.blockZ = Size.chunkToBlock(chunkZ);
|
||||
this.border = borderChunks;
|
||||
this.chunkSize = Size.chunks(size, borderChunks);
|
||||
this.blockSize = Size.blocks(size, borderChunks);
|
||||
this.disposalListener = disposalListener;
|
||||
this.disposableChunks = chunkSize.size * chunkSize.size;
|
||||
this.blocks = new GenCell[blockSize.total * blockSize.total];
|
||||
this.chunks = new GenChunk[chunkSize.total * chunkSize.total];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
int disposed = disposedChunks.incrementAndGet();
|
||||
if (disposed < disposableChunks) {
|
||||
return;
|
||||
}
|
||||
disposalListener.onDispose(this);
|
||||
}
|
||||
|
||||
public long getRegionId() {
|
||||
return NoiseUtil.seed(getRegionX(), getRegionZ());
|
||||
}
|
||||
|
||||
public int getRegionX() {
|
||||
return regionX;
|
||||
}
|
||||
|
||||
public int getRegionZ() {
|
||||
return regionZ;
|
||||
}
|
||||
|
||||
public int getBlockX() {
|
||||
return blockX;
|
||||
}
|
||||
|
||||
public int getBlockZ() {
|
||||
return blockZ;
|
||||
}
|
||||
|
||||
public int getOffsetChunks() {
|
||||
return border;
|
||||
}
|
||||
|
||||
public int getChunkCount() {
|
||||
return chunks.length;
|
||||
}
|
||||
|
||||
public int getBlockCount() {
|
||||
return blocks.length;
|
||||
}
|
||||
|
||||
public Size getChunkSize() {
|
||||
return chunkSize;
|
||||
}
|
||||
|
||||
public Size getBlockSize() {
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
public Filterable<Terrain> filterable() {
|
||||
return new FilterRegion();
|
||||
}
|
||||
|
||||
public Cell<Terrain> getCell(int blockX, int blockZ) {
|
||||
int relBlockX = blockSize.border + blockSize.mask(blockX);
|
||||
int relBlockZ = blockSize.border + blockSize.mask(blockZ);
|
||||
int index = blockSize.indexOf(relBlockX, relBlockZ);
|
||||
return blocks[index];
|
||||
}
|
||||
|
||||
public Cell<Terrain> getRawCell(int blockX, int blockZ) {
|
||||
int index = blockSize.indexOf(blockX, blockZ);
|
||||
return blocks[index];
|
||||
}
|
||||
|
||||
public ChunkReader getChunk(int chunkX, int chunkZ) {
|
||||
int relChunkX = chunkSize.border + chunkSize.mask(chunkX);
|
||||
int relChunkZ = chunkSize.border + chunkSize.mask(chunkZ);
|
||||
int index = chunkSize.indexOf(relChunkX, relChunkZ);
|
||||
return chunks[index];
|
||||
}
|
||||
|
||||
public void generate(Consumer<ChunkWriter> consumer) {
|
||||
for (int cz = 0; cz < chunkSize.total; cz++) {
|
||||
for (int cx = 0; cx < chunkSize.total; cx++) {
|
||||
int index = chunkSize.indexOf(cx, cz);
|
||||
GenChunk chunk = computeChunk(index, cx, cz);
|
||||
consumer.accept(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateBase(Heightmap heightmap) {
|
||||
for (int cz = 0; cz < chunkSize.total; cz++) {
|
||||
for (int cx = 0; cx < chunkSize.total; cx++) {
|
||||
int index = chunkSize.indexOf(cx, cz);
|
||||
GenChunk chunk = computeChunk(index, cx, cz);
|
||||
for (int dz = 0; dz < 16; dz++) {
|
||||
for (int dx = 0; dx < 16; dx++) {
|
||||
float x = chunk.getBlockX() + dx;
|
||||
float z = chunk.getBlockZ() + dz;
|
||||
Cell<Terrain> cell = chunk.genCell(dx, dz);
|
||||
heightmap.applyBase(cell, x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateRivers(Heightmap heightmap, RiverRegionList rivers) {
|
||||
for (int cz = 0; cz < chunkSize.total; cz++) {
|
||||
for (int cx = 0; cx < chunkSize.total; cx++) {
|
||||
int index = chunkSize.indexOf(cx, cz);
|
||||
GenChunk chunk = computeChunk(index, cx, cz);
|
||||
for (int dz = 0; dz < 16; dz++) {
|
||||
for (int dx = 0; dx < 16; dx++) {
|
||||
float x = chunk.getBlockX() + dx;
|
||||
float z = chunk.getBlockZ() + dz;
|
||||
Cell<Terrain> cell = chunk.genCell(dx, dz);
|
||||
heightmap.applyRivers(cell, x, z, rivers);
|
||||
heightmap.applyClimate(cell, x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void generateZoom(Heightmap heightmap, float offsetX, float offsetZ, float zoom) {
|
||||
float translateX = offsetX - ((blockSize.size * zoom) / 2F);
|
||||
float translateZ = offsetZ - ((blockSize.size * zoom) / 2F);
|
||||
for (int cz = 0; cz < chunkSize.total; cz++) {
|
||||
for (int cx = 0; cx < chunkSize.total; cx++) {
|
||||
int index = chunkSize.indexOf(cx, cz);
|
||||
GenChunk chunk = computeChunk(index, cx, cz);
|
||||
for (int dz = 0; dz < 16; dz++) {
|
||||
for (int dx = 0; dx < 16; dx++) {
|
||||
float x = ((chunk.getBlockX() + dx) * zoom) + translateX;
|
||||
float z = ((chunk.getBlockZ() + dz) * zoom) + translateZ;
|
||||
Cell<Terrain> cell = chunk.genCell(dx, dz);
|
||||
heightmap.apply(cell, x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void decorate(Collection<Decorator> decorators) {
|
||||
for (int dz = 0; dz < blockSize.total; dz++) {
|
||||
for (int dx = 0; dx < blockSize.total; dx++) {
|
||||
int index = blockSize.indexOf(dx, dz);
|
||||
GenCell cell = blocks[index];
|
||||
for (Decorator decorator : decorators) {
|
||||
if (decorator.apply(cell, getBlockX() + dx, getBlockZ() + dz)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void decorateZoom(Collection<Decorator> decorators, float offsetX, float offsetZ, float zoom) {
|
||||
float translateX = offsetX - ((blockSize.size * zoom) / 2F);
|
||||
float translateZ = offsetZ - ((blockSize.size * zoom) / 2F);
|
||||
for (int cz = 0; cz < chunkSize.total; cz++) {
|
||||
for (int cx = 0; cx < chunkSize.total; cx++) {
|
||||
int index = chunkSize.indexOf(cx, cz);
|
||||
GenChunk chunk = computeChunk(index, cx, cz);
|
||||
chunk.iterate((cell, dx, dz) -> {
|
||||
float x = ((chunk.getBlockX() + dx) * zoom) + translateX;
|
||||
float z = ((chunk.getBlockZ() + dz) * zoom) + translateZ;
|
||||
for (Decorator decorator : decorators) {
|
||||
decorator.apply(cell, x, z);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void iterate(Consumer<ChunkReader> consumer) {
|
||||
for (int cz = 0; cz < chunkSize.size; cz++) {
|
||||
int chunkZ = chunkSize.border + cz;
|
||||
for (int cx = 0; cx < chunkSize.size; cx++) {
|
||||
int chunkX = chunkSize.border + cx;
|
||||
int index = chunkSize.indexOf(chunkX, chunkZ);
|
||||
GenChunk chunk = chunks[index];
|
||||
consumer.accept(chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void iterate(Cell.Visitor<Terrain> visitor) {
|
||||
for (int dz = 0; dz < blockSize.size; dz++) {
|
||||
int z = blockSize.border + dz;
|
||||
for (int dx = 0; dx < blockSize.size; dx++) {
|
||||
int x = blockSize.border + dx;
|
||||
int index = blockSize.indexOf(x, z);
|
||||
GenCell cell = blocks[index];
|
||||
visitor.visit(cell, dx, dz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(int minX, int minZ, int maxX, int maxZ, Cell.Visitor<Terrain> visitor) {
|
||||
int regionMinX = getBlockX();
|
||||
int regionMinZ = getBlockZ();
|
||||
if (maxX < regionMinX || maxZ < regionMinZ) {
|
||||
return;
|
||||
}
|
||||
|
||||
int regionMaxX = getBlockX() + getBlockSize().size - 1;
|
||||
int regionMaxZ = getBlockZ() + getBlockSize().size - 1;
|
||||
if (minX > regionMaxX || maxZ > regionMaxZ) {
|
||||
return;
|
||||
}
|
||||
|
||||
minX = Math.max(minX, regionMinX);
|
||||
minZ = Math.max(minZ, regionMinZ);
|
||||
maxX = Math.min(maxX, regionMaxX);
|
||||
maxZ = Math.min(maxZ, regionMaxZ);
|
||||
|
||||
for (int z = minZ; z <= maxX; z++) {
|
||||
for (int x = minX; x <= maxZ; x++) {
|
||||
visitor.visit(getCell(x, z), x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private GenChunk computeChunk(int index, int chunkX, int chunkZ) {
|
||||
GenChunk chunk = chunks[index];
|
||||
if (chunk == null) {
|
||||
chunk = new GenChunk(chunkX, chunkZ);
|
||||
chunks[index] = chunk;
|
||||
}
|
||||
return chunk;
|
||||
}
|
||||
|
||||
private GenCell computeCell(int index) {
|
||||
GenCell cell = blocks[index];
|
||||
if (cell == null) {
|
||||
cell = new GenCell();
|
||||
blocks[index] = cell;
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
private static class GenCell extends Cell<Terrain> {}
|
||||
|
||||
private class GenChunk implements ChunkReader, ChunkWriter {
|
||||
|
||||
private final int chunkX;
|
||||
private final int chunkZ;
|
||||
private final int blockX;
|
||||
private final int blockZ;
|
||||
private final int regionBlockX;
|
||||
private final int regionBlockZ;
|
||||
|
||||
// the coordinate of the chunk within this region (relative to 0,0)
|
||||
private GenChunk(int regionChunkX, int regionChunkZ) {
|
||||
// the block coordinate of this chunk within this region (relative 0,0)
|
||||
this.regionBlockX = regionChunkX << 4;
|
||||
this.regionBlockZ = regionChunkZ << 4;
|
||||
// the real coordinate of this chunk within the world
|
||||
this.chunkX = Region.this.chunkX + regionChunkX - getOffsetChunks();
|
||||
this.chunkZ = Region.this.chunkZ + regionChunkZ - getOffsetChunks();
|
||||
// the real block coordinate of this chunk within the world
|
||||
this.blockX = chunkX << 4;
|
||||
this.blockZ = chunkZ << 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChunkX() {
|
||||
return chunkX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getChunkZ() {
|
||||
return chunkZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockX() {
|
||||
return blockX;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBlockZ() {
|
||||
return blockZ;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
Region.this.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cell<Terrain> getCell(int blockX, int blockZ) {
|
||||
int relX = regionBlockX + (blockX & 15);
|
||||
int relZ = regionBlockZ + (blockZ & 15);
|
||||
int index = blockSize.indexOf(relX, relZ);
|
||||
return blocks[index];
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cell<Terrain> genCell(int blockX, int blockZ) {
|
||||
int relX = regionBlockX + (blockX & 15);
|
||||
int relZ = regionBlockZ + (blockZ & 15);
|
||||
int index = blockSize.indexOf(relX, relZ);
|
||||
return computeCell(index);
|
||||
}
|
||||
}
|
||||
|
||||
private class FilterRegion implements Filterable<Terrain> {
|
||||
|
||||
@Override
|
||||
public Size getSize() {
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cell<Terrain>[] getBacking() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cell<Terrain> getCellRaw(int x, int z) {
|
||||
int index = blockSize.indexOf(x, z);
|
||||
if (index < 0 || index >= blocks.length) {
|
||||
return Cell.empty();
|
||||
}
|
||||
return blocks[index];
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package com.terraforged.core.region;
|
||||
|
||||
import com.terraforged.core.util.concurrent.Disposable;
|
||||
|
||||
public interface RegionFactory {
|
||||
|
||||
Region create(int regionX, int regionZ, int size, int borderChunks, Disposable.Listener<Region> listener);
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region;
|
||||
|
||||
public class Size {
|
||||
|
||||
public final int size;
|
||||
public final int total;
|
||||
public final int border;
|
||||
private final int mask;
|
||||
|
||||
public Size(int size, int border) {
|
||||
this.size = size;
|
||||
this.mask = size - 1;
|
||||
this.border = border;
|
||||
this.total = size + (2 * border);
|
||||
}
|
||||
|
||||
public int mask(int i) {
|
||||
return i & mask;
|
||||
}
|
||||
|
||||
public int indexOf(int x, int z) {
|
||||
return (z * total) + x;
|
||||
}
|
||||
|
||||
public static int chunkToBlock(int i) {
|
||||
return i << 4;
|
||||
}
|
||||
|
||||
public static int blockToChunk(int i) {
|
||||
return i >> 4;
|
||||
}
|
||||
|
||||
public static int count(int minX, int minZ, int maxX, int maxZ) {
|
||||
int dx = maxX - minX;
|
||||
int dz = maxZ - minZ;
|
||||
return dx * dz;
|
||||
}
|
||||
|
||||
public static Size chunks(int factor, int borderChunks) {
|
||||
int chunks = 1 << factor;
|
||||
return new Size(chunks, borderChunks);
|
||||
}
|
||||
|
||||
public static Size blocks(int factor, int borderChunks) {
|
||||
int chunks = 1 << factor;
|
||||
int blocks = chunks << 4;
|
||||
int borderBlocks = borderChunks << 4;
|
||||
return new Size(blocks, borderBlocks);
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region.chunk;
|
||||
|
||||
import com.terraforged.core.world.heightmap.Heightmap;
|
||||
|
||||
public class ChunkGenTask implements Runnable {
|
||||
|
||||
protected final ChunkWriter chunk;
|
||||
protected final Heightmap heightmap;
|
||||
|
||||
public ChunkGenTask(ChunkWriter chunk, Heightmap heightmap) {
|
||||
this.chunk = chunk;
|
||||
this.heightmap = heightmap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
chunk.generate((cell, dx, dz) -> {
|
||||
float x = chunk.getBlockX() + dx;
|
||||
float z = chunk.getBlockZ() + dz;
|
||||
heightmap.apply(cell, x, z);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region.chunk;
|
||||
|
||||
import com.terraforged.core.cell.Extent;
|
||||
import com.terraforged.core.util.concurrent.Disposable;
|
||||
|
||||
public interface ChunkHolder extends Extent, Disposable {
|
||||
|
||||
int getChunkX();
|
||||
|
||||
int getChunkZ();
|
||||
|
||||
int getBlockX();
|
||||
|
||||
int getBlockZ();
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region.chunk;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
|
||||
public interface ChunkReader extends ChunkHolder {
|
||||
|
||||
Cell<Terrain> getCell(int dx, int dz);
|
||||
|
||||
@Override
|
||||
default void visit(int minX, int minZ, int maxX, int maxZ, Cell.Visitor<Terrain> visitor) {
|
||||
int regionMinX = getBlockX();
|
||||
int regionMinZ = getBlockZ();
|
||||
if (maxX < regionMinX || maxZ < regionMinZ) {
|
||||
return;
|
||||
}
|
||||
|
||||
int regionMaxX = getBlockX() + 15;
|
||||
int regionMaxZ = getBlockZ() + 15;
|
||||
if (minX > regionMaxX || maxZ > regionMaxZ) {
|
||||
return;
|
||||
}
|
||||
|
||||
minX = Math.max(minX, regionMinX);
|
||||
minZ = Math.max(minZ, regionMinZ);
|
||||
maxX = Math.min(maxX, regionMaxX);
|
||||
maxZ = Math.min(maxZ, regionMaxZ);
|
||||
|
||||
for (int z = minZ; z <= maxX; z++) {
|
||||
for (int x = minX; x <= maxZ; x++) {
|
||||
visitor.visit(getCell(x, z), x, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default void iterate(Cell.Visitor<Terrain> visitor) {
|
||||
for (int dz = 0; dz < 16; dz++) {
|
||||
for (int dx = 0; dx < 16; dx++) {
|
||||
visitor.visit(getCell(dx, dz), dx, dz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default <C> void iterate(C context, Cell.ContextVisitor<C, Terrain> visitor) {
|
||||
for (int dz = 0; dz < 16; dz++) {
|
||||
for (int dx = 0; dx < 16; dx++) {
|
||||
visitor.visit(getCell(dx, dz), dx, dz, context);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region.chunk;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
|
||||
public interface ChunkWriter extends ChunkHolder {
|
||||
|
||||
Cell<Terrain> genCell(int dx, int dz);
|
||||
|
||||
default void generate(Cell.Visitor<Terrain> visitor) {
|
||||
for (int dz = 0; dz < 16; dz++) {
|
||||
for (int dx = 0; dx < 16; dx++) {
|
||||
visitor.visit(genCell(dx, dz), dx, dz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region.chunk;
|
||||
|
||||
import com.terraforged.core.world.heightmap.Heightmap;
|
||||
|
||||
public class ChunkZoomTask extends ChunkGenTask {
|
||||
|
||||
private final float translateX;
|
||||
private final float translateZ;
|
||||
private final float zoom;
|
||||
|
||||
public ChunkZoomTask(ChunkWriter chunk, Heightmap heightmap, float translateX, float translateZ, float zoom) {
|
||||
super(chunk, heightmap);
|
||||
this.translateX = translateX;
|
||||
this.translateZ = translateZ;
|
||||
this.zoom = zoom;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
chunk.generate((cell, dx, dz) -> {
|
||||
float x = ((chunk.getBlockX() + dx) * zoom) + translateX;
|
||||
float z = ((chunk.getBlockZ() + dz) * zoom) + translateZ;
|
||||
heightmap.apply(cell, x, z);
|
||||
});
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package com.terraforged.core.region.gen;
|
||||
|
||||
import com.terraforged.core.region.Region;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FutureRegion implements Future<Region>, Callable<Region> {
|
||||
|
||||
private final int rx;
|
||||
private final int rz;
|
||||
private final RegionGenerator generator;
|
||||
|
||||
private volatile Region result;
|
||||
|
||||
public FutureRegion(int rx, int rz, RegionGenerator generator) {
|
||||
this.rx = rx;
|
||||
this.rz = rz;
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region call() {
|
||||
Region region = result;
|
||||
if (region == null) {
|
||||
region = generator.generateRegion(rx, rz);
|
||||
result = region;
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return result != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region get() {
|
||||
return call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region get(long timeout, TimeUnit unit) {
|
||||
return get();
|
||||
}
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package com.terraforged.core.region.gen;
|
||||
|
||||
import com.terraforged.core.region.Region;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class FutureRegionZoom implements Future<Region>, Callable<Region> {
|
||||
|
||||
private final float cx;
|
||||
private final float cz;
|
||||
private final float zoom;
|
||||
private final boolean filters;
|
||||
private final RegionGenerator generator;
|
||||
|
||||
private volatile Region result;
|
||||
|
||||
public FutureRegionZoom(float cx, float cz, float zoom, boolean filters, RegionGenerator generator) {
|
||||
this.cx = cx;
|
||||
this.cz = cz;
|
||||
this.zoom = zoom;
|
||||
this.filters = filters;
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region call() {
|
||||
Region region = result;
|
||||
if (region == null) {
|
||||
region = generator.generateRegion(cx, cz, zoom, filters);
|
||||
result = region;
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCancelled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDone() {
|
||||
return result != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region get() {
|
||||
return call();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region get(long timeout, TimeUnit unit) {
|
||||
return get();
|
||||
}
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
package com.terraforged.core.region.gen;
|
||||
|
||||
import com.terraforged.core.world.WorldGenerator;
|
||||
import com.terraforged.core.world.WorldGeneratorFactory;
|
||||
import com.terraforged.core.world.rivermap.RiverRegionList;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class GenContext {
|
||||
|
||||
public final WorldGenerator generator;
|
||||
public final RiverRegionList rivers = new RiverRegionList();
|
||||
|
||||
public GenContext(WorldGenerator generator) {
|
||||
this.generator = generator;
|
||||
}
|
||||
|
||||
public static Supplier<GenContext> supplier(WorldGeneratorFactory factory) {
|
||||
return () -> new GenContext(factory.get());
|
||||
}
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region.gen;
|
||||
|
||||
import com.terraforged.core.region.Region;
|
||||
import com.terraforged.core.region.chunk.ChunkReader;
|
||||
import com.terraforged.core.util.concurrent.Disposable;
|
||||
import com.terraforged.core.util.concurrent.cache.Cache;
|
||||
import com.terraforged.core.util.concurrent.cache.CacheEntry;
|
||||
import com.terraforged.core.world.heightmap.RegionExtent;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class RegionCache implements RegionExtent, Disposable.Listener<Region> {
|
||||
|
||||
private final boolean queuing;
|
||||
private final RegionGenerator generator;
|
||||
private final Cache<CacheEntry<Region>> cache;
|
||||
|
||||
public RegionCache(boolean queueNeighbours, RegionGenerator generator) {
|
||||
this.queuing = queueNeighbours;
|
||||
this.generator = new RegionGenerator(generator, this);
|
||||
this.cache = new Cache<>(60, 30, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDispose(Region region) {
|
||||
cache.remove(region.getRegionId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int chunkToRegion(int coord) {
|
||||
return generator.chunkToRegion(coord);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Region> getRegionAsync(int regionX, int regionZ) {
|
||||
return generator.generate(regionX, regionZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkReader getChunk(int chunkX, int chunkZ) {
|
||||
int regionX = generator.chunkToRegion(chunkX);
|
||||
int regionZ = generator.chunkToRegion(chunkZ);
|
||||
Region region = getRegion(regionX, regionZ);
|
||||
return region.getChunk(chunkX, chunkZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region getRegion(int regionX, int regionZ) {
|
||||
Region region = computeRegion(regionX, regionZ).get();
|
||||
|
||||
if (queuing) {
|
||||
queueNeighbours(regionX, regionZ);
|
||||
}
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
private CacheEntry<Region> computeRegion(int regionX, int regionZ) {
|
||||
long id = NoiseUtil.seed(regionX, regionZ);
|
||||
return cache.computeIfAbsent(id, l -> generator.compute(regionX, regionZ));
|
||||
}
|
||||
|
||||
public CacheEntry<Region> queueRegion(int regionX, int regionZ) {
|
||||
long id = NoiseUtil.seed(regionX, regionZ);
|
||||
return cache.computeIfAbsent(id, l -> generator.queue(regionX, regionZ));
|
||||
}
|
||||
|
||||
private void queueNeighbours(int regionX, int regionZ) {
|
||||
for (int z = -1; z <= 1; z++) {
|
||||
for (int x = -1; x <= 1; x++){
|
||||
if (x == 0 && z == 0) {
|
||||
continue;
|
||||
}
|
||||
queueRegion(regionX + x, regionZ + z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region.gen;
|
||||
|
||||
import com.terraforged.core.world.WorldGeneratorFactory;
|
||||
|
||||
public interface RegionCacheFactory {
|
||||
|
||||
RegionCache create(WorldGeneratorFactory factory);
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.region.gen;
|
||||
|
||||
import com.terraforged.core.region.Region;
|
||||
import com.terraforged.core.region.RegionFactory;
|
||||
import com.terraforged.core.region.legacy.LegacyRegion;
|
||||
import com.terraforged.core.util.concurrent.Disposable;
|
||||
import com.terraforged.core.util.concurrent.ObjectPool;
|
||||
import com.terraforged.core.util.concurrent.ThreadPool;
|
||||
import com.terraforged.core.util.concurrent.cache.CacheEntry;
|
||||
import com.terraforged.core.world.WorldGenerator;
|
||||
import com.terraforged.core.world.WorldGeneratorFactory;
|
||||
import com.terraforged.core.world.heightmap.RegionExtent;
|
||||
import com.terraforged.core.world.rivermap.RiverRegionList;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class RegionGenerator implements RegionExtent {
|
||||
|
||||
private final int factor;
|
||||
private final int border;
|
||||
private final RegionFactory regions;
|
||||
private final ThreadPool threadPool;
|
||||
private final ObjectPool<GenContext> genPool;
|
||||
private final Disposable.Listener<Region> disposalListener;
|
||||
|
||||
private RegionGenerator(Builder builder) {
|
||||
this.factor = builder.factor;
|
||||
this.border = builder.border;
|
||||
this.threadPool = builder.threadPool;
|
||||
this.regions = builder.regionFactory;
|
||||
this.genPool = new ObjectPool<>(6, GenContext.supplier(builder.factory));
|
||||
this.disposalListener = region -> {};
|
||||
}
|
||||
|
||||
protected RegionGenerator(RegionGenerator from, Disposable.Listener<Region> listener) {
|
||||
this.factor = from.factor;
|
||||
this.border = from.border;
|
||||
this.threadPool = from.threadPool;
|
||||
this.regions = from.regions;
|
||||
this.genPool = from.genPool;
|
||||
this.disposalListener = listener;
|
||||
}
|
||||
|
||||
public RegionCache toCache() {
|
||||
return toCache(true);
|
||||
}
|
||||
|
||||
public RegionCache toCache(boolean queueNeighbours) {
|
||||
return new RegionCache(queueNeighbours, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int chunkToRegion(int i) {
|
||||
return i >> factor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Region getRegion(int regionX, int regionZ) {
|
||||
return generateRegion(regionX, regionZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Region> getRegionAsync(int regionX, int regionZ) {
|
||||
return generate(regionX, regionZ);
|
||||
}
|
||||
|
||||
public CompletableFuture<Region> generate(int regionX, int regionZ) {
|
||||
return CompletableFuture.supplyAsync(() -> generateRegion(regionX, regionZ), threadPool);
|
||||
}
|
||||
|
||||
public CompletableFuture<Region> generate(float centerX, float centerZ, float zoom, boolean filter) {
|
||||
return CompletableFuture.supplyAsync(() -> generateRegion(centerX, centerZ, zoom, filter), threadPool);
|
||||
}
|
||||
|
||||
public CacheEntry<Region> compute(int regionX, int regionZ) {
|
||||
return CacheEntry.supply(new FutureRegion(regionX, regionZ, this));
|
||||
}
|
||||
|
||||
public CacheEntry<Region> compute(float centerX, float centerZ, float zoom, boolean filter) {
|
||||
return CacheEntry.supply(new FutureRegionZoom(centerX, centerZ, zoom, filter, this));
|
||||
}
|
||||
|
||||
public CacheEntry<Region> queue(int regionX, int regionZ) {
|
||||
return CacheEntry.supplyAsync(new FutureRegion(regionX, regionZ, this), threadPool);
|
||||
}
|
||||
|
||||
public CacheEntry<Region> queue(float centerX, float centerZ, float zoom, boolean filter) {
|
||||
return CacheEntry.supplyAsync(new FutureRegionZoom(centerX, centerZ, zoom, filter, this), threadPool);
|
||||
}
|
||||
|
||||
public Region generateRegion(int regionX, int regionZ) {
|
||||
try (ObjectPool.Item<GenContext> item = genPool.get()) {
|
||||
RiverRegionList rivers = item.getValue().rivers;
|
||||
WorldGenerator generator = item.getValue().generator;
|
||||
Region region = regions.create(regionX, regionZ, factor, border, disposalListener);
|
||||
generator.getHeightmap().getRiverMap().getRivers(region, rivers);
|
||||
region.generateBase(generator.getHeightmap());
|
||||
region.generateRivers(generator.getHeightmap(), rivers);
|
||||
postProcess(region, generator);
|
||||
rivers.clear();
|
||||
return region;
|
||||
}
|
||||
}
|
||||
|
||||
private void postProcess(Region region, WorldGenerator generator) {
|
||||
generator.getFilters().apply(region);
|
||||
region.decorate(generator.getDecorators().getDecorators());
|
||||
}
|
||||
|
||||
public Region generateRegion(float centerX, float centerZ, float zoom, boolean filter) {
|
||||
try (ObjectPool.Item<GenContext> item = genPool.get()) {
|
||||
WorldGenerator generator = item.getValue().generator;
|
||||
Region region = regions.create(0, 0, factor, border, disposalListener);
|
||||
region.generateZoom(generator.getHeightmap(), centerX, centerZ, zoom);
|
||||
postProcess(region, generator, centerX, centerZ, zoom, filter);
|
||||
return region;
|
||||
}
|
||||
}
|
||||
|
||||
private void postProcess(Region region, WorldGenerator generator, float centerX, float centerZ, float zoom, boolean filter) {
|
||||
if (filter) {
|
||||
generator.getFilters().apply(region);
|
||||
}
|
||||
region.decorateZoom(generator.getDecorators().getDecorators(), centerX, centerZ, zoom);
|
||||
}
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
|
||||
private int factor = 0;
|
||||
private int border = 0;
|
||||
private ThreadPool threadPool;
|
||||
private WorldGeneratorFactory factory;
|
||||
private RegionFactory regionFactory = Region::new;
|
||||
|
||||
public Builder size(int factor, int border) {
|
||||
return factor(factor).border(border);
|
||||
}
|
||||
|
||||
public Builder factor(int factor) {
|
||||
this.factor = factor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder border(int border) {
|
||||
this.border = border;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder pool(ThreadPool threadPool) {
|
||||
this.threadPool = threadPool;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder regions(RegionFactory factory) {
|
||||
this.regionFactory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder legacy(boolean legacy) {
|
||||
if (legacy) {
|
||||
return regions(LegacyRegion::new);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder factory(WorldGeneratorFactory factory) {
|
||||
this.factory = factory;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RegionGenerator build() {
|
||||
return new RegionGenerator(this);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package com.terraforged.core.region.legacy;
|
||||
|
||||
import com.terraforged.core.region.Region;
|
||||
import com.terraforged.core.util.concurrent.Disposable;
|
||||
|
||||
/**
|
||||
* This is here to provide compatibility for versions 0.0.2 and below which contained a
|
||||
* bug where Regions generated with an x,z offset equal to the size of the chunk border
|
||||
* around the region (x16) ie 32 blocks
|
||||
*/
|
||||
public class LegacyRegion extends Region {
|
||||
|
||||
public LegacyRegion(int regionX, int regionZ, int size, int borderChunks, Disposable.Listener<Region> listener) {
|
||||
super(regionX, regionZ, size, borderChunks, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used when calculating the 'real world' chunk position of the chunk-view
|
||||
* and subsequently the 'real world' block start position. In versions 0.0.2 and
|
||||
* below, no offset was being deducted, so return 0 here to maintain that broken
|
||||
* behaviour... RIP :/
|
||||
*/
|
||||
@Override
|
||||
public int getOffsetChunks() {
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.settings;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||
import com.terraforged.core.util.serialization.annotation.Range;
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
import com.terraforged.core.world.biome.BiomeType;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class BiomeSettings {
|
||||
|
||||
public BiomeGroup desert = new BiomeGroup(BiomeType.DESERT);
|
||||
public BiomeGroup steppe = new BiomeGroup(BiomeType.STEPPE);
|
||||
public BiomeGroup coldSteppe = new BiomeGroup(BiomeType.COLD_STEPPE);
|
||||
public BiomeGroup grassland = new BiomeGroup(BiomeType.GRASSLAND);
|
||||
public BiomeGroup savanna = new BiomeGroup(BiomeType.SAVANNA);
|
||||
public BiomeGroup taiga = new BiomeGroup(BiomeType.TAIGA);
|
||||
public BiomeGroup temperateForest = new BiomeGroup(BiomeType.TEMPERATE_FOREST);
|
||||
public BiomeGroup temperateRainForest = new BiomeGroup(BiomeType.TEMPERATE_RAINFOREST);
|
||||
public BiomeGroup tropicalRainForest = new BiomeGroup(BiomeType.TROPICAL_RAINFOREST);
|
||||
public BiomeGroup tundra = new BiomeGroup(BiomeType.TUNDRA);
|
||||
|
||||
public List<BiomeGroup> asList() {
|
||||
return Arrays.asList(
|
||||
desert,
|
||||
steppe,
|
||||
coldSteppe,
|
||||
grassland,
|
||||
savanna,
|
||||
taiga,
|
||||
temperateForest,
|
||||
temperateRainForest,
|
||||
tropicalRainForest,
|
||||
tundra
|
||||
);
|
||||
}
|
||||
|
||||
public Map<BiomeType, BiomeGroup> asMap() {
|
||||
return asList().stream().collect(Collectors.toMap(g -> g.type, g -> g));
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public static class BiomeGroup {
|
||||
|
||||
public BiomeType type;
|
||||
|
||||
public BiomeWeight[] biomes = new BiomeWeight[0];
|
||||
|
||||
public BiomeGroup() {
|
||||
|
||||
}
|
||||
|
||||
public BiomeGroup(BiomeType biomeType) {
|
||||
this.type = biomeType;
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public static class BiomeWeight {
|
||||
|
||||
public String id;
|
||||
|
||||
@Range(min = 0, max = 50)
|
||||
@Comment("Controls how common this biome type is")
|
||||
public int weight;
|
||||
|
||||
public BiomeWeight() {
|
||||
|
||||
}
|
||||
|
||||
public BiomeWeight(String id, int weight) {
|
||||
this.id = id;
|
||||
this.weight = weight;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.terraforged.core.settings;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||
import com.terraforged.core.util.serialization.annotation.Range;
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.Source;
|
||||
|
||||
@Serializable
|
||||
public class ClimateSettings {
|
||||
|
||||
public RangeValue moisture = new RangeValue(0, 1F);
|
||||
|
||||
public RangeValue temperature = new RangeValue(0, 1F);
|
||||
|
||||
@Serializable
|
||||
public static class RangeValue {
|
||||
|
||||
@Range(min = 0F, max = 1F)
|
||||
@Comment("The lower limit of the range")
|
||||
public float min;
|
||||
|
||||
@Range(min = 0F, max = 1F)
|
||||
@Comment("The upper limit of the range")
|
||||
public float max;
|
||||
|
||||
public RangeValue() {
|
||||
this(0, 1);
|
||||
}
|
||||
|
||||
public RangeValue(float min, float max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
public float getMin() {
|
||||
return Math.min(min, max);
|
||||
}
|
||||
|
||||
public float getMax() {
|
||||
return Math.max(min, max);
|
||||
}
|
||||
|
||||
public Module clamp(Module module) {
|
||||
float min = getMin();
|
||||
float max = getMax();
|
||||
float range = max - min;
|
||||
if (range == 0) {
|
||||
return Source.constant(min);
|
||||
}
|
||||
return module.scale(range).bias(min);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.settings;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||
import com.terraforged.core.util.serialization.annotation.Range;
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
|
||||
@Serializable
|
||||
public class FilterSettings {
|
||||
|
||||
public Erosion erosion = new Erosion();
|
||||
|
||||
public Smoothing smoothing = new Smoothing();
|
||||
|
||||
@Serializable
|
||||
public static class Erosion {
|
||||
|
||||
@Range(min = 1000, max = 50000)
|
||||
@Comment("Controls the number of erosion iterations")
|
||||
public int iterations = 12000;
|
||||
|
||||
@Range(min = 0F, max = 1F)
|
||||
@Comment("Controls how quickly material dissolves (during erosion)")
|
||||
public float erosionRate = 0.5F;
|
||||
|
||||
@Range(min = 0F, max = 1F)
|
||||
@Comment("Controls how quickly material is deposited (during erosion)")
|
||||
public float depositeRate = 0.2F;
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public static class Smoothing {
|
||||
|
||||
@Range(min = 0, max = 5)
|
||||
@Comment("Controls the number of smoothing iterations")
|
||||
public int iterations = 1;
|
||||
|
||||
@Range(min = 0, max = 5)
|
||||
@Comment("Controls the smoothing radius")
|
||||
public float smoothingRadius = 1.75F;
|
||||
|
||||
@Range(min = 0, max = 1)
|
||||
@Comment("Controls how strongly smoothing is applied")
|
||||
public float smoothingRate = 0.85F;
|
||||
}
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.settings;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||
import com.terraforged.core.util.serialization.annotation.Name;
|
||||
import com.terraforged.core.util.serialization.annotation.Range;
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.Source;
|
||||
|
||||
@Serializable
|
||||
public class GeneratorSettings {
|
||||
|
||||
public transient long seed = 0L;
|
||||
|
||||
/**
|
||||
* WORLD PROPERTIES
|
||||
*/
|
||||
public World world = new World();
|
||||
|
||||
/**
|
||||
* TERRAIN PROPERTIES
|
||||
*/
|
||||
public Land land = new Land();
|
||||
|
||||
/**
|
||||
* BIOME PROPERTIES
|
||||
*/
|
||||
public Biome biome = new Biome();
|
||||
|
||||
public BiomeNoise biomeEdgeNoise = new BiomeNoise();
|
||||
|
||||
@Serializable
|
||||
public static class World {
|
||||
|
||||
@Range(min = 0, max = 256)
|
||||
@Comment("Controls the world height")
|
||||
public int worldHeight = 256;
|
||||
|
||||
@Range(min = 0, max = 255)
|
||||
@Comment("Controls the sea level")
|
||||
public int seaLevel = 63;
|
||||
|
||||
@Range(min = 0F, max = 1F)
|
||||
@Comment("Controls the amount of ocean between continents")
|
||||
public float oceanSize = 0.25F;
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public static class Land {
|
||||
|
||||
@Range(min = 100, max = 10000)
|
||||
@Comment("Controls the size of continents")
|
||||
public int continentScale = 4000;
|
||||
|
||||
@Range(min = 250, max = 5000)
|
||||
@Name("Mountain Range Scale")
|
||||
@Comment("Controls the size of mountain ranges")
|
||||
public int mountainScale = 950;
|
||||
|
||||
@Range(min = 125, max = 5000)
|
||||
@Comment("Controls the size of terrain regions")
|
||||
public int regionSize = 1000;
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public static class Biome {
|
||||
|
||||
@Range(min = 50, max = 1000)
|
||||
@Comment("Controls the size of individual biomes")
|
||||
public int biomeSize = 200;
|
||||
|
||||
@Range(min = 1, max = 500)
|
||||
@Comment("Controls the scale of shape distortion for biomes")
|
||||
public int biomeWarpScale = 35;
|
||||
|
||||
@Range(min = 1, max = 500)
|
||||
@Comment("Controls the strength of shape distortion for biomes")
|
||||
public int biomeWarpStrength = 70;
|
||||
}
|
||||
|
||||
@Serializable
|
||||
public static class BiomeNoise {
|
||||
|
||||
@Comment("The noise type")
|
||||
public Source type = Source.PERLIN;
|
||||
|
||||
@Range(min = 1, max = 500)
|
||||
@Comment("Controls the scale of the noise")
|
||||
public int scale = 8;
|
||||
|
||||
@Range(min = 1, max = 5)
|
||||
@Comment("Controls the number of noise octaves")
|
||||
public int octaves = 2;
|
||||
|
||||
@Range(min = 0F, max = 5.5F)
|
||||
@Comment("Controls the gain subsequent noise octaves")
|
||||
public float gain = 0.5F;
|
||||
|
||||
@Range(min = 0F, max = 10.5F)
|
||||
@Comment("Controls the lacunarity of subsequent noise octaves")
|
||||
public float lacunarity = 2.5F;
|
||||
|
||||
@Range(min = 1, max = 500)
|
||||
@Comment("Controls the strength of the noise")
|
||||
public int strength = 24;
|
||||
|
||||
public Module build(int seed) {
|
||||
return Source.build(seed, scale, octaves).gain(gain).lacunarity(lacunarity).build(type).bias(-0.5);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.settings;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||
import com.terraforged.core.util.serialization.annotation.Range;
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
|
||||
@Serializable
|
||||
public class RiverSettings {
|
||||
|
||||
/**
|
||||
* RIVER PROPERTIES
|
||||
*/
|
||||
@Range(min = 0.0F, max = 5F)
|
||||
@Comment("Controls how frequently rivers generate")
|
||||
public float riverFrequency = 1;
|
||||
|
||||
public River primaryRivers = new River(5, 2, 8, 25, 8, 0.75F);
|
||||
|
||||
public River secondaryRiver = new River(4, 1, 6, 15, 5, 0.75F);
|
||||
|
||||
public River tertiaryRivers = new River(3, 0, 4, 10, 4, 0.75F);
|
||||
|
||||
public Lake lake = new Lake();
|
||||
|
||||
@Serializable
|
||||
public static class River {
|
||||
|
||||
@Range(min = 1, max = 10)
|
||||
@Comment("Controls the depth of the river")
|
||||
public int bedDepth;
|
||||
|
||||
@Range(min = 0, max = 10)
|
||||
@Comment("Controls the height of river banks")
|
||||
public int minBankHeight;
|
||||
|
||||
@Range(min = 1, max = 10)
|
||||
@Comment("Controls the height of river banks")
|
||||
public int maxBankHeight;
|
||||
|
||||
@Range(min = 1, max = 20)
|
||||
@Comment("Controls the river-bed width")
|
||||
public int bedWidth;
|
||||
|
||||
@Range(min = 1, max = 50)
|
||||
@Comment("Controls the river-banks width")
|
||||
public int bankWidth;
|
||||
|
||||
@Range(min = 0.0F, max = 1.0F)
|
||||
@Comment("Controls how much rivers taper")
|
||||
public float fade;
|
||||
|
||||
public River() {
|
||||
}
|
||||
|
||||
public River(int depth, int minBank, int maxBank, int outer, int inner, float fade) {
|
||||
this.minBankHeight = minBank;
|
||||
this.maxBankHeight = maxBank;
|
||||
this.bankWidth = outer;
|
||||
this.bedWidth = inner;
|
||||
this.bedDepth = depth;
|
||||
this.fade = fade;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Lake {
|
||||
|
||||
@Range(min = 0.0F, max = 1.0F)
|
||||
@Comment("Controls the chance of a lake spawning")
|
||||
public float chance = 0.2F;
|
||||
|
||||
@Range(min = 0F, max = 1F)
|
||||
@Comment("The minimum distance along a river that a lake will spawn")
|
||||
public float minStartDistance = 0.03F;
|
||||
|
||||
@Range(min = 0F, max = 1F)
|
||||
@Comment("The maximum distance along a river that a lake will spawn")
|
||||
public float maxStartDistance = 0.07F;
|
||||
|
||||
@Range(min = 1, max = 20)
|
||||
@Comment("The max depth of the lake")
|
||||
public int depth = 10;
|
||||
|
||||
@Range(min = 10, max = 50)
|
||||
@Comment("The minimum size of the lake")
|
||||
public int sizeMin = 50;
|
||||
|
||||
@Range(min = 50, max = 150)
|
||||
@Comment("The maximum size of the lake")
|
||||
public int sizeMax = 100;
|
||||
|
||||
@Range(min = 1, max = 10)
|
||||
@Comment("The minimum bank height")
|
||||
public int minBankHeight = 2;
|
||||
|
||||
@Range(min = 1, max = 10)
|
||||
@Comment("The maximum bank height")
|
||||
public int maxBankHeight = 10;
|
||||
|
||||
public Lake() {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.settings;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
|
||||
@Serializable
|
||||
public class Settings {
|
||||
|
||||
public GeneratorSettings generator = new GeneratorSettings();
|
||||
|
||||
public ClimateSettings climate = new ClimateSettings();
|
||||
|
||||
public RiverSettings rivers = new RiverSettings();
|
||||
|
||||
public FilterSettings filters = new FilterSettings();
|
||||
|
||||
public TerrainSettings terrain = new TerrainSettings();
|
||||
|
||||
public BiomeSettings biomes = new BiomeSettings();
|
||||
}
|
@ -1,91 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.settings;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||
import com.terraforged.core.util.serialization.annotation.Range;
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
import com.terraforged.core.world.terrain.TerrainPopulator;
|
||||
import me.dags.noise.Module;
|
||||
|
||||
@Serializable
|
||||
public class TerrainSettings {
|
||||
|
||||
@Range(min = 0, max = 1)
|
||||
@Comment("Globally controls the vertical scaling of terrain")
|
||||
public float globalVerticalScale = 0.985F;
|
||||
|
||||
@Range(min = 0, max = 5)
|
||||
@Comment("Globally controls the horizontal scaling of terrain")
|
||||
public float globalHorizontalScale = 1.0F;
|
||||
|
||||
public Terrain steppe = new Terrain(5F, 1F, 1F);
|
||||
public Terrain plains = new Terrain(5F, 1F, 1F);
|
||||
public Terrain hills = new Terrain(2F, 1F, 1F);
|
||||
public Terrain dales = new Terrain(2F, 1F, 1F);
|
||||
public Terrain plateau = new Terrain(2F, 1F, 1F);
|
||||
public Terrain badlands = new Terrain(2F, 1F, 1F);
|
||||
public Terrain torridonian = new Terrain(0.5F, 1F, 1F);
|
||||
public Terrain mountains = new Terrain(0.5F, 1F, 1F);
|
||||
public Terrain volcano = new Terrain(1F, 1F, 1F);
|
||||
|
||||
@Serializable
|
||||
public static class Terrain {
|
||||
|
||||
@Range(min = 0, max = 10)
|
||||
@Comment("Controls how common this terrain type is")
|
||||
public float weight = 1F;
|
||||
|
||||
@Range(min = 0, max = 2)
|
||||
@Comment("Controls the base height of this terrain")
|
||||
public float baseScale = 1F;
|
||||
|
||||
@Range(min = 0F, max = 10F)
|
||||
@Comment("Stretches or compresses the terrain vertically")
|
||||
public float verticalScale = 1F;
|
||||
|
||||
@Range(min = 0F, max = 10F)
|
||||
@Comment("Stretches or compresses the terrain horizontally")
|
||||
public float horizontalScale = 1F;
|
||||
|
||||
public Terrain() {
|
||||
|
||||
}
|
||||
|
||||
public Terrain(float weight, float vertical, float horizontal) {
|
||||
this.weight = weight;
|
||||
this.verticalScale = vertical;
|
||||
this.horizontalScale = horizontal;
|
||||
}
|
||||
|
||||
public Module apply(double bias, double scale, Module module) {
|
||||
double moduleBias = bias * baseScale;
|
||||
double moduleScale = scale * verticalScale;
|
||||
Module outputModule = module.scale(moduleScale).bias(moduleBias);
|
||||
return TerrainPopulator.clamp(outputModule);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,156 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util;
|
||||
|
||||
public class PosIterator {
|
||||
|
||||
private final int minX;
|
||||
private final int minZ;
|
||||
private final int maxX;
|
||||
private final int maxY;
|
||||
private final int maxZ;
|
||||
private final int size;
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
private int z;
|
||||
private int index = -1;
|
||||
|
||||
public PosIterator(int x, int y, int z, int width, int height, int length) {
|
||||
this.x = x - 1;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.minX = x;
|
||||
this.minZ = z;
|
||||
this.maxX = x + width;
|
||||
this.maxY = y + height;
|
||||
this.maxZ = z + length;
|
||||
this.size = (width * height * length) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Steps the iterator forward one position if there there is a new position within it's x/y/z bounds.
|
||||
*
|
||||
* @return true if the an increment was made, false if the maximum x,y,z coord has been reached
|
||||
*/
|
||||
public boolean next() {
|
||||
if (x + 1 < maxX) {
|
||||
x += 1;
|
||||
index++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (z + 1 < maxZ) {
|
||||
x = minX;
|
||||
z += 1;
|
||||
index++;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (y + 1 < maxY) {
|
||||
x = minX - 1;
|
||||
z = minZ;
|
||||
y += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public int index() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public int x() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int y() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int z() {
|
||||
return z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over a 2D area in the x-z planes, centered on x:z, with the given radius
|
||||
*
|
||||
* Iteration Order:
|
||||
* 1. Increments the x-axis from x - radius to x + radius (inclusive), then:
|
||||
* 2. Increments the z-axis once, resets the x-axis to x - radius, then:
|
||||
* 3. Repeats steps 1 & 2 until z reaches z + radius
|
||||
*/
|
||||
public static PosIterator radius2D(int x, int z, int radius) {
|
||||
int startX = x - radius;
|
||||
int startZ = z - radius;
|
||||
int size = radius * 2 + 1;
|
||||
return new PosIterator(startX, 0, startZ, size, 0, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over a 3D volume, centered on x:y:z, with the given radius
|
||||
*
|
||||
* Iteration Order:
|
||||
* 1. Increments the x-axis (starting from x - radius) up to x + radius (inclusive), then:
|
||||
* 2. Increments the z-axis once (starting from z - radius) and resets the x-axis to x - radius, then:
|
||||
* 3. Increments the y-axis once (starting from y - radius), resets the x & z axes to x - radius & z - radius
|
||||
* respectively, then:
|
||||
* 4. Repeats steps 1-3 until y reaches y + radius
|
||||
*/
|
||||
public static PosIterator radius3D(int x, int y, int z, int radius) {
|
||||
int startX = x - radius;
|
||||
int startY = y - radius;
|
||||
int startZ = z - radius;
|
||||
int size = radius * 2 + 1;
|
||||
return new PosIterator(startX, startY, startZ, size, size, size);
|
||||
}
|
||||
|
||||
public static PosIterator area(int x, int z, int width, int length) {
|
||||
return new PosIterator(x, 0, z, width, 0, length);
|
||||
}
|
||||
|
||||
public static PosIterator volume3D(int x, int y, int z, int width, int height, int length) {
|
||||
return new PosIterator(x, y, z, width, height, length);
|
||||
}
|
||||
|
||||
public static PosIterator range2D(int minX, int minZ, int maxX, int maxZ) {
|
||||
int width = maxX - minX;
|
||||
int length = maxZ - minZ;
|
||||
return new PosIterator(minX, 0, minZ, width, 0, length);
|
||||
}
|
||||
|
||||
public static PosIterator range2D(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
||||
int width = 1 + maxX - minX;
|
||||
int height = 1 + maxY - minY;
|
||||
int length = 1 + maxZ - minZ;
|
||||
return new PosIterator(minX, minY, minZ, width, height, length);
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util;
|
||||
|
||||
public class Seed {
|
||||
|
||||
private final Seed root;
|
||||
|
||||
private final int value;
|
||||
private int seed;
|
||||
|
||||
public Seed(long seed) {
|
||||
this((int) seed);
|
||||
}
|
||||
|
||||
public Seed(int seed) {
|
||||
this.value = seed;
|
||||
this.seed = seed;
|
||||
this.root = this;
|
||||
}
|
||||
|
||||
private Seed(Seed root) {
|
||||
this.root = root;
|
||||
this.seed = root.next();
|
||||
this.value = seed;
|
||||
}
|
||||
|
||||
public int next() {
|
||||
return ++root.seed;
|
||||
}
|
||||
|
||||
public int get() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Seed nextSeed() {
|
||||
return new Seed(root);
|
||||
}
|
||||
|
||||
public Seed reset() {
|
||||
this.seed = value;
|
||||
return this;
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.heightmap.Levels;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.Source;
|
||||
|
||||
import java.util.function.BiPredicate;
|
||||
|
||||
public class VariablePredicate {
|
||||
|
||||
private final Module module;
|
||||
private final BiPredicate<Cell<Terrain>, Float> predicate;
|
||||
|
||||
public VariablePredicate(Module module, BiPredicate<Cell<Terrain>, Float> predicate) {
|
||||
this.module = module;
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
public boolean test(Cell<Terrain> cell, float x, float z) {
|
||||
return predicate.test(cell, module.getValue(x, z));
|
||||
}
|
||||
|
||||
public static VariablePredicate height(Seed seed, Levels levels, int min, int max, int size, int octaves) {
|
||||
float bias = levels.scale(min);
|
||||
float scale = levels.scale(max - min);
|
||||
Module source = Source.perlin(seed.next(), size, 1).scale(scale).bias(bias);
|
||||
return new VariablePredicate(source, (cell, height) -> cell.value < height);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package com.terraforged.core.util.concurrent;
|
||||
|
||||
public interface Disposable {
|
||||
|
||||
void dispose();
|
||||
|
||||
interface Listener<T> {
|
||||
|
||||
void onDispose(T t);
|
||||
}
|
||||
}
|
@ -1,103 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.concurrent;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class ObjectPool<T> {
|
||||
|
||||
private final int capacity;
|
||||
private final List<Item<T>> pool;
|
||||
private final Supplier<? extends T> supplier;
|
||||
|
||||
public ObjectPool(int size, Supplier<? extends T> supplier) {
|
||||
this.capacity = size;
|
||||
this.pool = new ArrayList<>(size);
|
||||
this.supplier = supplier;
|
||||
}
|
||||
|
||||
public Item<T> get() {
|
||||
synchronized (pool) {
|
||||
if (pool.size() > 0) {
|
||||
return pool.remove(pool.size() - 1).retain();
|
||||
}
|
||||
}
|
||||
return new Item<>(supplier.get(), this);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
synchronized (pool) {
|
||||
return pool.size();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean restore(Item<T> item) {
|
||||
synchronized (pool) {
|
||||
int size = pool.size();
|
||||
if (size < capacity) {
|
||||
pool.add(item);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static class Item<T> implements AutoCloseable {
|
||||
|
||||
private final T value;
|
||||
private final ObjectPool<T> pool;
|
||||
|
||||
private boolean released = false;
|
||||
|
||||
private Item(T value, ObjectPool<T> pool) {
|
||||
this.value = value;
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
if (!released) {
|
||||
released = true;
|
||||
released = pool.restore(this);
|
||||
}
|
||||
}
|
||||
|
||||
private Item<T> retain() {
|
||||
released = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
release();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.concurrent;
|
||||
|
||||
import com.terraforged.core.util.concurrent.batcher.AsyncBatcher;
|
||||
import com.terraforged.core.util.concurrent.batcher.Batcher;
|
||||
import com.terraforged.core.util.concurrent.batcher.SyncBatcher;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinTask;
|
||||
|
||||
public class ThreadPool implements Executor {
|
||||
|
||||
private static final ThreadPool instance = create("TF", defaultPoolSize());
|
||||
|
||||
private final ForkJoinPool service;
|
||||
|
||||
private ThreadPool(ForkJoinPool service) {
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
service.submit(command);
|
||||
}
|
||||
|
||||
public ForkJoinTask<?> submit(Runnable runnable) {
|
||||
return service.submit(runnable);
|
||||
}
|
||||
|
||||
public <T> ForkJoinTask<T> submit(Callable<T> callable) {
|
||||
return service.submit(callable);
|
||||
}
|
||||
|
||||
public Batcher batcher(int size) {
|
||||
return new AsyncBatcher(service, size);
|
||||
}
|
||||
|
||||
public static ThreadPool getPool() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static ThreadPool create(String name, int size) {
|
||||
if (size < 2) {
|
||||
return new SingleThreadExecutor();
|
||||
}
|
||||
return new ThreadPool(createPool(name, size));
|
||||
}
|
||||
|
||||
public static ForkJoinPool createPool(String name, int size) {
|
||||
return new ForkJoinPool(size, new WorkerFactory.ForkJoin(name), null, true);
|
||||
}
|
||||
|
||||
private static int defaultPoolSize() {
|
||||
int threads = Runtime.getRuntime().availableProcessors();
|
||||
return Math.max(1, (int) ((threads / 3F) * 2F));
|
||||
}
|
||||
|
||||
private static class SingleThreadExecutor extends ThreadPool {
|
||||
|
||||
private SingleThreadExecutor() {
|
||||
super(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Runnable command) {
|
||||
command.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForkJoinTask<?> submit(Runnable runnable) {
|
||||
ForkJoinTask<?> task = ForkJoinTask.adapt(runnable);
|
||||
task.invoke();
|
||||
return task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ForkJoinTask<T> submit(Callable<T> callable) {
|
||||
ForkJoinTask<T> task = ForkJoinTask.adapt(callable);
|
||||
task.invoke();
|
||||
return task;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Batcher batcher(int size) {
|
||||
return new SyncBatcher();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package com.terraforged.core.util.concurrent;
|
||||
|
||||
import java.util.concurrent.ForkJoinPool;
|
||||
import java.util.concurrent.ForkJoinWorkerThread;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
// As DefaultThreadPool but with custom thread names
|
||||
public class WorkerFactory implements ThreadFactory {
|
||||
|
||||
protected final String prefix;
|
||||
protected final ThreadGroup group;
|
||||
protected final AtomicInteger threadNumber = new AtomicInteger(1);
|
||||
|
||||
public WorkerFactory(String name) {
|
||||
group = Thread.currentThread().getThreadGroup();
|
||||
prefix = name + "-Worker-";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable task) {
|
||||
Thread thread = new Thread(group, task);
|
||||
thread.setDaemon(true);
|
||||
thread.setName(prefix + threadNumber.getAndIncrement());
|
||||
return thread;
|
||||
}
|
||||
|
||||
public static class ForkJoin extends WorkerFactory implements ForkJoinPool.ForkJoinWorkerThreadFactory {
|
||||
|
||||
public ForkJoin(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
|
||||
ForkJoinWorkerThread thread = new ForkJoinWorkerThread(pool) {};
|
||||
thread.setDaemon(true);
|
||||
thread.setName(prefix + threadNumber.getAndIncrement());
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.concurrent.batcher;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class AsyncBatcher implements Batcher {
|
||||
|
||||
private final List<Future<?>> tasks;
|
||||
private final ExecutorService executor;
|
||||
|
||||
public AsyncBatcher(ExecutorService executor, int size) {
|
||||
this.executor = executor;
|
||||
this.tasks = new ArrayList<>(size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submit(Runnable task) {
|
||||
tasks.add(executor.submit(task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submit(Callable<?> task) {
|
||||
tasks.add(executor.submit(task));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
boolean hasMore = true;
|
||||
while (hasMore) {
|
||||
hasMore = false;
|
||||
for (Future<?> future : tasks) {
|
||||
if (!future.isDone()) {
|
||||
hasMore = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
tasks.clear();
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.concurrent.batcher;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public interface Batcher extends AutoCloseable {
|
||||
|
||||
void submit(Runnable task);
|
||||
|
||||
void submit(Callable<?> task);
|
||||
|
||||
@Override
|
||||
void close();
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.concurrent.batcher;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class SyncBatcher implements Batcher {
|
||||
|
||||
@Override
|
||||
public void submit(Runnable task) {
|
||||
task.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void submit(Callable<?> task) {
|
||||
try {
|
||||
task.call();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
|
||||
}
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package com.terraforged.core.util.concurrent.cache;
|
||||
|
||||
import com.terraforged.core.util.concurrent.ThreadPool;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.LongFunction;
|
||||
|
||||
public class Cache<V extends ExpiringEntry> implements Runnable {
|
||||
|
||||
private final long expireMS;
|
||||
private final long intervalMS;
|
||||
private final SynchronizedLongMap<V> map;
|
||||
private final ThreadPool threadPool = ThreadPool.getPool();
|
||||
|
||||
private volatile long timestamp = 0L;
|
||||
|
||||
public Cache(long expireTime, long interval, TimeUnit unit) {
|
||||
this.expireMS = unit.toMillis(expireTime);
|
||||
this.intervalMS = unit.toMillis(interval);
|
||||
this.map = new SynchronizedLongMap<>(100);
|
||||
}
|
||||
|
||||
public void remove(long key) {
|
||||
map.remove(key);
|
||||
}
|
||||
|
||||
public V computeIfAbsent(long key, LongFunction<V> func) {
|
||||
V v = map.computeIfAbsent(key, func);
|
||||
queueUpdate();
|
||||
return v;
|
||||
}
|
||||
|
||||
private void queueUpdate() {
|
||||
long now = System.currentTimeMillis();
|
||||
if (now - timestamp > intervalMS) {
|
||||
timestamp = now;
|
||||
threadPool.submit(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
final long now = timestamp;
|
||||
map.removeIf(val -> now - val.getTimestamp() > expireMS);
|
||||
}
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package com.terraforged.core.util.concurrent.cache;
|
||||
|
||||
import com.terraforged.core.util.concurrent.ThreadPool;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ForkJoinTask;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
public class CacheEntry<T> implements ExpiringEntry {
|
||||
|
||||
private volatile long timestamp;
|
||||
private final Future<T> task;
|
||||
|
||||
public CacheEntry(Future<T> task) {
|
||||
this.task = task;
|
||||
this.timestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getTimestamp() {
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
public boolean isDone() {
|
||||
return task.isDone();
|
||||
}
|
||||
|
||||
public T get() {
|
||||
if (task instanceof ForkJoinTask) {
|
||||
return ((ForkJoinTask<T>) task).join();
|
||||
}
|
||||
|
||||
try {
|
||||
return task.get();
|
||||
} catch (InterruptedException | ExecutionException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> CacheEntry<T> supply(Future<T> future) {
|
||||
return new CacheEntry<>(future);
|
||||
}
|
||||
|
||||
public static <T> CacheEntry<T> supplyAsync(Callable<T> callable, ThreadPool executor) {
|
||||
return new CacheEntry<>(executor.submit(callable));
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package com.terraforged.core.util.concurrent.cache;
|
||||
|
||||
public interface ExpiringEntry {
|
||||
|
||||
long getTimestamp();
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package com.terraforged.core.util.concurrent.cache;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||
|
||||
import java.util.function.LongFunction;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class SynchronizedLongMap<V> {
|
||||
|
||||
private final Object lock;
|
||||
private final Long2ObjectOpenHashMap<V> map;
|
||||
|
||||
public SynchronizedLongMap(int size) {
|
||||
this.map = new Long2ObjectOpenHashMap<>(size);
|
||||
this.lock = this;
|
||||
}
|
||||
|
||||
public void remove(long key) {
|
||||
synchronized (lock) {
|
||||
map.remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void put(long key, V v) {
|
||||
synchronized (lock) {
|
||||
map.put(key, v);
|
||||
}
|
||||
}
|
||||
|
||||
public V get(long key) {
|
||||
synchronized (lock) {
|
||||
return map.get(key);
|
||||
}
|
||||
}
|
||||
|
||||
public V computeIfAbsent(long key, LongFunction<V> func) {
|
||||
synchronized (lock) {
|
||||
return map.computeIfAbsent(key, func);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeIf(Predicate<V> predicate) {
|
||||
synchronized (lock) {
|
||||
ObjectIterator<Long2ObjectMap.Entry<V>> iterator = map.long2ObjectEntrySet().fastIterator();
|
||||
while (iterator.hasNext()) {
|
||||
if (predicate.test(iterator.next().getValue())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,163 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.grid;
|
||||
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class FixedGrid<T> implements Iterable<MappedList<FixedList<T>>> {
|
||||
|
||||
private final MappedList<MappedList<FixedList<T>>> grid;
|
||||
|
||||
private FixedGrid(MappedList<MappedList<FixedList<T>>> grid) {
|
||||
this.grid = grid;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return grid.size();
|
||||
}
|
||||
|
||||
public FixedList<T> get(float x, float y) {
|
||||
return grid.get(y).get(x);
|
||||
}
|
||||
|
||||
public T get(float x, float y, float z) {
|
||||
MappedList<FixedList<T>> row = grid.get(y);
|
||||
FixedList<T> cell = row.get(x);
|
||||
return cell.get(z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<MappedList<FixedList<T>>> iterator() {
|
||||
return grid.iterator();
|
||||
}
|
||||
|
||||
public static <T> FixedGrid<T> create(List<List<List<T>>> grid, float minX, float minY, float rangeX, float rangeY) {
|
||||
List<MappedList<FixedList<T>>> list = new ArrayList<>();
|
||||
for (List<List<T>> src : grid) {
|
||||
List<FixedList<T>> row = new ArrayList<>(src.size());
|
||||
for (List<T> cell : src) {
|
||||
row.add(FixedList.of(cell));
|
||||
}
|
||||
list.add(MappedList.of(row, minX, rangeX));
|
||||
}
|
||||
return new FixedGrid<>(MappedList.of(list, minY, rangeY));
|
||||
}
|
||||
|
||||
public static <T> FixedGrid<T> generate(int size, List<T> values, Function<T, Float> xFunc, Function<T, Float> yFunc) {
|
||||
List<List<List<T>>> src = createList(size, () -> createList(size, ArrayList::new));
|
||||
List<List<List<T>>> dest = createList(size, () -> createList(size, ArrayList::new));
|
||||
|
||||
float minX = 1F;
|
||||
float maxX = 0F;
|
||||
float minY = 1F;
|
||||
float maxY = 0F;
|
||||
for (T value : values) {
|
||||
float x = xFunc.apply(value);
|
||||
float y = yFunc.apply(value);
|
||||
minX = Math.min(minX, x);
|
||||
maxX = Math.max(maxX, x);
|
||||
minY = Math.min(minY, y);
|
||||
maxY = Math.max(maxY, y);
|
||||
}
|
||||
|
||||
int maxIndex = size - 1;
|
||||
float rangeX = maxX - minX;
|
||||
float rangeY = maxY - minY;
|
||||
for (T value : values) {
|
||||
float colVal = (xFunc.apply(value) - minX) / rangeX;
|
||||
float rowVal = (yFunc.apply(value) - minY) / rangeY;
|
||||
int colIndex = NoiseUtil.round(maxIndex * colVal);
|
||||
int rowIndex = NoiseUtil.round(maxIndex * rowVal);
|
||||
List<List<T>> row = src.get(rowIndex);
|
||||
List<T> group = row.get(colIndex);
|
||||
group.add(value);
|
||||
}
|
||||
|
||||
for (int y = 0; y < size; y++) {
|
||||
List<List<T>> srcRow = src.get(y);
|
||||
List<List<T>> destRow = dest.get(y);
|
||||
for (int x = 0; x < size; x++) {
|
||||
List<T> srcGroup = srcRow.get(x);
|
||||
List<T> destGroup = destRow.get(x);
|
||||
if (srcGroup.isEmpty()) {
|
||||
float fx = minX + (x / (float) maxIndex) * rangeX;
|
||||
float fy = minY + (x / (float) maxIndex) * rangeY;
|
||||
addClosest(values, destGroup, fx, fy, xFunc, yFunc);
|
||||
} else {
|
||||
destGroup.addAll(srcGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return create(dest, minX, minY, rangeX, rangeY);
|
||||
}
|
||||
|
||||
private static <T> void addClosest(List<T> source, List<T> dest, float fx, float fy, Function<T, Float> xFunc, Function<T, Float> yFunc) {
|
||||
float dist2 = Float.MAX_VALUE;
|
||||
Map<T, Float> distances = new HashMap<>();
|
||||
for (T t : source) {
|
||||
if (!distances.containsKey(t)) {
|
||||
float dx = fx - xFunc.apply(t);
|
||||
float dy = fy - yFunc.apply(t);
|
||||
float d2 = dx * dx + dy * dy;
|
||||
distances.put(t, d2);
|
||||
if (d2 < dist2) {
|
||||
dist2 = d2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dist2 <= 0) {
|
||||
dist2 = 1F;
|
||||
}
|
||||
|
||||
List<T> sorted = new ArrayList<>(distances.keySet());
|
||||
sorted.sort((o1, o2) -> Float.compare(distances.getOrDefault(o1, Float.MAX_VALUE), distances.getOrDefault(o2, Float.MAX_VALUE)));
|
||||
|
||||
for (T t : sorted) {
|
||||
float d2 = distances.get(t);
|
||||
if (d2 / dist2 < 1.025F) {
|
||||
dest.add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> List<T> createList(int size, Supplier<T> supplier) {
|
||||
List<T> list = new ArrayList<>();
|
||||
while (list.size() < size) {
|
||||
list.add(supplier.get());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.grid;
|
||||
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class FixedList<T> implements Iterable<T> {
|
||||
|
||||
private final int maxIndex;
|
||||
private final T[] elements;
|
||||
|
||||
FixedList(T[] elements) {
|
||||
this.maxIndex = elements.length - 1;
|
||||
this.elements = elements;
|
||||
}
|
||||
|
||||
public T get(int index) {
|
||||
if (index < 0) {
|
||||
return elements[0];
|
||||
}
|
||||
if (index > maxIndex) {
|
||||
return elements[maxIndex];
|
||||
}
|
||||
return elements[index];
|
||||
}
|
||||
|
||||
public T get(float value) {
|
||||
return get(indexOf(value));
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return elements.length;
|
||||
}
|
||||
|
||||
public int indexOf(float value) {
|
||||
return NoiseUtil.round(value * maxIndex);
|
||||
}
|
||||
|
||||
public Set<T> uniqueValues() {
|
||||
Set<T> set = new HashSet<>();
|
||||
Collections.addAll(set, elements);
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return new Iterator<T>() {
|
||||
|
||||
private int index = 0;
|
||||
|
||||
@Override
|
||||
public boolean hasNext() {
|
||||
return index < elements.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T next() {
|
||||
return elements[index++];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> FixedList<T> of(List<T> list) {
|
||||
return new FixedList<>((T[]) list.toArray());
|
||||
}
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.grid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MappedList<T> extends FixedList<T> {
|
||||
|
||||
private final float min;
|
||||
private final float range;
|
||||
|
||||
public MappedList(T[] elements, float min, float range) {
|
||||
super(elements);
|
||||
this.min = min;
|
||||
this.range = range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(float value) {
|
||||
return super.indexOf((value - min) / range);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> MappedList<T> of(List<T> list, float min, float range) {
|
||||
return new MappedList<>((T[]) list.toArray(), min, range);
|
||||
}
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package com.terraforged.core.util.points;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.region.Region;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.Source;
|
||||
import me.dags.noise.util.Vec2i;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
public class Poisson {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Region region = new Region(0, 0, 5, 2);
|
||||
BufferedImage image = new BufferedImage(region.getBlockSize().size, region.getBlockSize().size, BufferedImage.TYPE_INT_RGB);
|
||||
points(region, 123,8, 20F, 0.8F);
|
||||
render(region, image);
|
||||
|
||||
JFrame frame = new JFrame();
|
||||
frame.add(new JLabel(new ImageIcon(image)));
|
||||
frame.pack();
|
||||
frame.setVisible(true);
|
||||
frame.setResizable(false);
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
}
|
||||
|
||||
private static void points(Region region, int seed, int scale, float radius, float threshold) {
|
||||
region.generate(chunk -> chunk.generate((cell, dx, dz) -> {}));
|
||||
|
||||
Module noise = Source.simplex(seed, scale, 1);
|
||||
|
||||
int gridSize = (int) Math.ceil(region.getBlockSize().size / radius);
|
||||
Vec2i[][] grid = new Vec2i[gridSize][gridSize];
|
||||
|
||||
for (int dz = 0; dz < region.getBlockSize().size; dz++) {
|
||||
for (int dx = 0; dx < region.getBlockSize().size; dx++) {
|
||||
int x = region.getBlockX() + dx;
|
||||
int z = region.getBlockZ() + dz;
|
||||
float value = noise.getValue(x, z);
|
||||
region.getCell(dx, dz).value = value;
|
||||
if (true) continue;
|
||||
|
||||
if (value > threshold) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int gridX = (int) (dx / radius);
|
||||
int gridZ = (int) (dz / radius);
|
||||
Vec2i point = grid[gridZ][gridX];
|
||||
|
||||
if (point != null) {
|
||||
Cell<?> current = region.getCell(point.x, point.y);
|
||||
if (current.value > value) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
region.getCell(dx, dz).value = value;
|
||||
grid[gridZ][gridX] = new Vec2i(dx, dz);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void render(Region region, BufferedImage image) {
|
||||
region.iterate((cell, dx, dz) -> {
|
||||
if (cell.value == 0) {
|
||||
return;
|
||||
}
|
||||
int w = (int) (cell.value * 255);
|
||||
image.setRGB(dx, dz, new Color(w, w, w).getRGB());
|
||||
});
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Comment {
|
||||
|
||||
String[] value();
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Name {
|
||||
|
||||
String value();
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Option {
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.FIELD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Range {
|
||||
|
||||
float min();
|
||||
|
||||
float max();
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Serializable {
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.serializer;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class Deserializer {
|
||||
|
||||
public void deserialize(Reader reader, Object object) throws Throwable {
|
||||
Class<?> type = object.getClass();
|
||||
for (String name : reader.getKeys()) {
|
||||
if (name.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Reader child = reader.getChild(name);
|
||||
Field field = type.getField(name);
|
||||
if (Serializer.isSerializable(field)) {
|
||||
field.setAccessible(true);
|
||||
fromValue(child, object, field);
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fromValue(Reader reader, Object object, Field field) throws Throwable {
|
||||
if (field.getType() == int.class) {
|
||||
field.set(object, reader.getInt("value"));
|
||||
return;
|
||||
}
|
||||
if (field.getType() == float.class) {
|
||||
field.set(object, reader.getFloat("value"));
|
||||
return;
|
||||
}
|
||||
if (field.getType() == boolean.class) {
|
||||
field.set(object, reader.getString("value").equals("true"));
|
||||
return;
|
||||
}
|
||||
if (field.getType() == String.class) {
|
||||
field.set(object, reader.getString("value"));
|
||||
return;
|
||||
}
|
||||
if (field.getType().isEnum()) {
|
||||
String name = reader.getString("value");
|
||||
for (Enum<?> e : field.getType().asSubclass(Enum.class).getEnumConstants()) {
|
||||
if (e.name().equals(name)) {
|
||||
field.set(object, e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (field.getType().isAnnotationPresent(Serializable.class)) {
|
||||
Reader child = reader.getChild("value");
|
||||
Object value = field.getType().newInstance();
|
||||
deserialize(child, value);
|
||||
field.set(object, value);
|
||||
return;
|
||||
}
|
||||
if (field.getType().isArray()) {
|
||||
Class<?> type = field.getType().getComponentType();
|
||||
if (type.isAnnotationPresent(Serializable.class)) {
|
||||
Reader child = reader.getChild("value");
|
||||
Object array = Array.newInstance(type, child.getSize());
|
||||
for (int i = 0; i < child.getSize(); i++) {
|
||||
Object value = type.newInstance();
|
||||
deserialize(child.getChild(i), value);
|
||||
Array.set(array, i, value);
|
||||
}
|
||||
field.set(object, array);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String getName(String name) {
|
||||
StringBuilder sb = new StringBuilder(name.length());
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char c = name.charAt(i);
|
||||
if (i == 0) {
|
||||
c = Character.toLowerCase(c);
|
||||
} else if (c == ' ' && i + 1 < name.length()) {
|
||||
c = Character.toUpperCase(name.charAt(++i));
|
||||
}
|
||||
sb.append(c);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.serializer;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public interface Reader {
|
||||
|
||||
int getSize();
|
||||
|
||||
Reader getChild(String key);
|
||||
|
||||
Reader getChild(int index);
|
||||
|
||||
Collection<String> getKeys();
|
||||
|
||||
String getString();
|
||||
|
||||
boolean getBool();
|
||||
|
||||
float getFloat();
|
||||
|
||||
int getInt();
|
||||
|
||||
default String getString(String key) {
|
||||
return getChild(key).getString();
|
||||
}
|
||||
|
||||
default boolean getBool(String key) {
|
||||
return getChild(key).getBool();
|
||||
}
|
||||
|
||||
default float getFloat(String key) {
|
||||
return getChild(key).getFloat();
|
||||
}
|
||||
|
||||
default int getInt(String key) {
|
||||
return getChild(key).getInt();
|
||||
}
|
||||
|
||||
default String getString(int index) {
|
||||
return getChild(index).getString();
|
||||
}
|
||||
|
||||
default boolean getBool(int index) {
|
||||
return getChild(index).getBool();
|
||||
}
|
||||
|
||||
default float getFloat(int index) {
|
||||
return getChild(index).getFloat();
|
||||
}
|
||||
|
||||
default int getInt(int index) {
|
||||
return getChild(index).getInt();
|
||||
}
|
||||
|
||||
default void writeTo(Object object) throws Throwable {
|
||||
new Deserializer().deserialize(this, object);
|
||||
}
|
||||
}
|
@ -1,191 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.serializer;
|
||||
|
||||
import com.terraforged.core.util.serialization.annotation.Comment;
|
||||
import com.terraforged.core.util.serialization.annotation.Name;
|
||||
import com.terraforged.core.util.serialization.annotation.Range;
|
||||
import com.terraforged.core.util.serialization.annotation.Serializable;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class Serializer {
|
||||
|
||||
public void serialize(Object object, Writer writer) throws IllegalAccessException {
|
||||
if (object.getClass().isArray()) {
|
||||
writer.beginArray();
|
||||
int length = Array.getLength(object);
|
||||
for (int i = 0; i < length; i++) {
|
||||
Object element = Array.get(object, i);
|
||||
serialize(element, writer);
|
||||
}
|
||||
writer.endArray();
|
||||
} else if (!object.getClass().isPrimitive()) {
|
||||
int order = 0;
|
||||
writer.beginObject();
|
||||
for (Field field : object.getClass().getFields()) {
|
||||
if (Serializer.isSerializable(field)) {
|
||||
field.setAccessible(true);
|
||||
write(object, field, order, writer);
|
||||
order++;
|
||||
}
|
||||
}
|
||||
writer.endObject();
|
||||
}
|
||||
}
|
||||
|
||||
private void write(Object object, Field field, int order, Writer writer) throws IllegalAccessException {
|
||||
if (field.getType() == int.class) {
|
||||
writer.name(field.getName());
|
||||
writer.beginObject();
|
||||
writer.name("value").value((int) field.get(object));
|
||||
writeMeta(field, order, writer);
|
||||
writer.endObject();
|
||||
return;
|
||||
}
|
||||
if (field.getType() == float.class) {
|
||||
writer.name(field.getName());
|
||||
writer.beginObject();
|
||||
writer.name("value").value((float) field.get(object));
|
||||
writeMeta(field, order, writer);
|
||||
writer.endObject();
|
||||
return;
|
||||
}
|
||||
if (field.getType() == String.class) {
|
||||
writer.name(field.getName());
|
||||
writer.beginObject();
|
||||
writer.name("value").value((String) field.get(object));
|
||||
writeMeta(field, order, writer);
|
||||
writer.endObject();
|
||||
return;
|
||||
}
|
||||
if (field.getType() == boolean.class) {
|
||||
writer.name(field.getName());
|
||||
writer.beginObject();
|
||||
writer.name("value").value("" + (field.get(object)));
|
||||
writeMeta(field, order, writer);
|
||||
writer.endObject();
|
||||
}
|
||||
if (field.getType().isEnum()) {
|
||||
writer.name(field.getName());
|
||||
writer.beginObject();
|
||||
writer.name("value").value(((Enum<?>) field.get(object)).name());
|
||||
writeMeta(field, order, writer);
|
||||
writer.endObject();
|
||||
return;
|
||||
}
|
||||
if (field.getType().isArray()) {
|
||||
if (field.getType().getComponentType().isAnnotationPresent(Serializable.class)) {
|
||||
writer.name(field.getName());
|
||||
writer.beginObject();
|
||||
writer.name("value");
|
||||
serialize(field.get(object), writer);
|
||||
writeMeta(field, order, writer);
|
||||
writer.endObject();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (field.getType().isAnnotationPresent(Serializable.class)) {
|
||||
writer.name(field.getName());
|
||||
writer.beginObject();
|
||||
writer.name("value");
|
||||
serialize(field.get(object), writer);
|
||||
writeMeta(field, order, writer);
|
||||
writer.endObject();
|
||||
}
|
||||
}
|
||||
|
||||
private void writeMeta(Field field, int order, Writer writer) {
|
||||
writer.name("#display").value(getName(field));
|
||||
writer.name("#order").value(order);
|
||||
|
||||
Range range = field.getAnnotation(Range.class);
|
||||
if (range != null) {
|
||||
if (field.getType() == int.class) {
|
||||
writer.name("#min").value((int) range.min());
|
||||
writer.name("#max").value((int) range.max());
|
||||
} else {
|
||||
writer.name("#min").value(range.min());
|
||||
writer.name("#max").value(range.max());
|
||||
}
|
||||
}
|
||||
|
||||
Comment comment = field.getAnnotation(Comment.class);
|
||||
if (comment != null) {
|
||||
writer.name("#comment");
|
||||
writer.beginArray();
|
||||
for (String line : comment.value()) {
|
||||
writer.value(line);
|
||||
}
|
||||
writer.endArray();
|
||||
}
|
||||
|
||||
if (field.getType() == boolean.class) {
|
||||
writer.name("#options");
|
||||
writer.beginArray();
|
||||
writer.value("true");
|
||||
writer.value("false");
|
||||
writer.endArray();
|
||||
}
|
||||
|
||||
if (field.getType().isEnum()) {
|
||||
writer.name("#options");
|
||||
writer.beginArray();
|
||||
for (Enum<?> o : field.getType().asSubclass(Enum.class).getEnumConstants()) {
|
||||
writer.value(o.name());
|
||||
}
|
||||
writer.endArray();
|
||||
}
|
||||
}
|
||||
|
||||
private static String getName(Field field) {
|
||||
Name nameMeta = field.getAnnotation(Name.class);
|
||||
|
||||
String name = nameMeta == null ? field.getName() : nameMeta.value();
|
||||
StringBuilder sb = new StringBuilder(name.length() * 2);
|
||||
for (int i = 0; i < name.length(); i++) {
|
||||
char c = name.charAt(i);
|
||||
if (i == 0) {
|
||||
c = Character.toUpperCase(c);
|
||||
} else if (Character.isUpperCase(c)) {
|
||||
sb.append(' ');
|
||||
}
|
||||
|
||||
sb.append(c);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
protected static boolean isSerializable(Field field) {
|
||||
int modifiers = field.getModifiers();
|
||||
return Modifier.isPublic(modifiers)
|
||||
&& !Modifier.isFinal(modifiers)
|
||||
&& !Modifier.isStatic(modifiers)
|
||||
&& !Modifier.isTransient(modifiers);
|
||||
}
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.util.serialization.serializer;
|
||||
|
||||
public interface Writer {
|
||||
|
||||
Writer name(String name);
|
||||
|
||||
Writer beginObject();
|
||||
|
||||
Writer endObject();
|
||||
|
||||
Writer beginArray();
|
||||
|
||||
Writer endArray();
|
||||
|
||||
Writer value(String value);
|
||||
|
||||
Writer value(float value);
|
||||
|
||||
Writer value(int value);
|
||||
|
||||
default void readFrom(Object value) throws IllegalAccessException {
|
||||
new Serializer().serialize(value, this);
|
||||
}
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world;
|
||||
|
||||
import com.terraforged.core.settings.Settings;
|
||||
import com.terraforged.core.util.Seed;
|
||||
import com.terraforged.core.world.heightmap.Levels;
|
||||
import com.terraforged.core.world.terrain.Terrains;
|
||||
import com.terraforged.core.world.terrain.provider.StandardTerrainProvider;
|
||||
import com.terraforged.core.world.terrain.provider.TerrainProviderFactory;
|
||||
|
||||
public class GeneratorContext {
|
||||
|
||||
public final Seed seed;
|
||||
public final Levels levels;
|
||||
public final Terrains terrain;
|
||||
public final Settings settings;
|
||||
public final TerrainProviderFactory terrainFactory;
|
||||
|
||||
public GeneratorContext(Terrains terrain, Settings settings) {
|
||||
this(terrain, settings, StandardTerrainProvider::new);
|
||||
}
|
||||
|
||||
public GeneratorContext(Terrains terrain, Settings settings, TerrainProviderFactory terrainFactory) {
|
||||
this.terrain = terrain;
|
||||
this.settings = settings;
|
||||
this.seed = new Seed(settings.generator.seed);
|
||||
this.levels = new Levels(settings.generator);
|
||||
this.terrainFactory = terrainFactory;
|
||||
}
|
||||
|
||||
private GeneratorContext(GeneratorContext src) {
|
||||
seed = new Seed(src.seed.get());
|
||||
levels = src.levels;
|
||||
terrain = src.terrain;
|
||||
settings = src.settings;
|
||||
terrainFactory = src.terrainFactory;
|
||||
}
|
||||
|
||||
public GeneratorContext copy() {
|
||||
return new GeneratorContext(this);
|
||||
}
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world;
|
||||
|
||||
import com.terraforged.core.world.decorator.Decorator;
|
||||
import com.terraforged.core.world.decorator.DesertStacks;
|
||||
import com.terraforged.core.world.decorator.Wetlands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldDecorators {
|
||||
|
||||
private final List<Decorator> decorators;
|
||||
|
||||
public WorldDecorators(GeneratorContext context) {
|
||||
context = context.copy();
|
||||
List<Decorator> list = new ArrayList<>();
|
||||
list.add(new DesertStacks(context.seed, context.levels));
|
||||
list.add(new Wetlands(context.seed, context.terrain, context.levels));
|
||||
decorators = Collections.unmodifiableList(list);
|
||||
}
|
||||
|
||||
public List<Decorator> getDecorators() {
|
||||
return decorators;
|
||||
}
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world;
|
||||
|
||||
import com.terraforged.core.filter.Erosion;
|
||||
import com.terraforged.core.filter.Filterable;
|
||||
import com.terraforged.core.filter.Smoothing;
|
||||
import com.terraforged.core.filter.Steepness;
|
||||
import com.terraforged.core.region.Region;
|
||||
import com.terraforged.core.settings.FilterSettings;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
|
||||
public class WorldFilters {
|
||||
|
||||
private final Erosion erosion;
|
||||
private final Smoothing smoothing;
|
||||
private final Steepness steepness;
|
||||
private final FilterSettings settings;
|
||||
|
||||
public WorldFilters(GeneratorContext context) {
|
||||
context = context.copy();
|
||||
this.settings = context.settings.filters;
|
||||
this.erosion = new Erosion(context.settings, context.levels);
|
||||
this.smoothing = new Smoothing(context.settings, context.levels);
|
||||
this.steepness = new Steepness(1, 10F, context.terrain, context.levels);
|
||||
}
|
||||
|
||||
public void apply(Region region) {
|
||||
Filterable<Terrain> map = region.filterable();
|
||||
erosion.apply(map, region.getRegionX(), region.getRegionZ(), settings.erosion.iterations);
|
||||
smoothing.apply(map, region.getRegionX(), region.getRegionZ(), settings.smoothing.iterations);
|
||||
steepness.apply(map, region.getRegionX(), region.getRegionZ(), 1);
|
||||
}
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world;
|
||||
|
||||
import com.terraforged.core.world.heightmap.Heightmap;
|
||||
|
||||
public class WorldGenerator {
|
||||
|
||||
private final Heightmap heightmap;
|
||||
private final WorldFilters filters;
|
||||
private final WorldDecorators decorators;
|
||||
|
||||
public WorldGenerator(Heightmap heightmap, WorldDecorators decorators, WorldFilters filters) {
|
||||
this.filters = filters;
|
||||
this.heightmap = heightmap;
|
||||
this.decorators = decorators;
|
||||
}
|
||||
|
||||
public Heightmap getHeightmap() {
|
||||
return heightmap;
|
||||
}
|
||||
|
||||
public WorldFilters getFilters() {
|
||||
return filters;
|
||||
}
|
||||
|
||||
public WorldDecorators getDecorators() {
|
||||
return decorators;
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world;
|
||||
|
||||
import com.terraforged.core.world.climate.Climate;
|
||||
import com.terraforged.core.world.heightmap.Heightmap;
|
||||
import com.terraforged.core.world.heightmap.WorldHeightmap;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class WorldGeneratorFactory implements Supplier<WorldGenerator> {
|
||||
|
||||
private final GeneratorContext context;
|
||||
|
||||
private final Heightmap heightmap;
|
||||
private final WorldDecorators decorators;
|
||||
|
||||
public WorldGeneratorFactory(GeneratorContext context) {
|
||||
this.context = context;
|
||||
this.heightmap = new WorldHeightmap(context);
|
||||
this.decorators = new WorldDecorators(context);
|
||||
}
|
||||
|
||||
public WorldGeneratorFactory(GeneratorContext context, Heightmap heightmap) {
|
||||
this.context = context;
|
||||
this.heightmap = heightmap;
|
||||
this.decorators = new WorldDecorators(context);
|
||||
}
|
||||
|
||||
public Heightmap getHeightmap() {
|
||||
return heightmap;
|
||||
}
|
||||
|
||||
public Climate getClimate() {
|
||||
return getHeightmap().getClimate();
|
||||
}
|
||||
|
||||
public WorldDecorators getDecorators() {
|
||||
return decorators;
|
||||
}
|
||||
|
||||
public WorldFilters getFilters() {
|
||||
return new WorldFilters(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WorldGenerator get() {
|
||||
return new WorldGenerator(heightmap, decorators, getFilters());
|
||||
}
|
||||
}
|
@ -1,159 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world.biome;
|
||||
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class BiomeData implements Comparable<BiomeData> {
|
||||
|
||||
private static float[] bounds = {0, 1 / 3F, 2 / 3F, 1F};
|
||||
|
||||
public static final List<BiomeData> BIOMES = new ArrayList<>();
|
||||
public static BiomeData DEFAULT = new BiomeData("none", "", 1, 0.5F, 0.5F);
|
||||
|
||||
public final String name;
|
||||
|
||||
public final Object reference;
|
||||
public final float color;
|
||||
public final float rainfall;
|
||||
public final float temperature;
|
||||
|
||||
public BiomeData(String name, Object reference, float color, float rainfall, float temperature) {
|
||||
this.reference = reference;
|
||||
this.name = name;
|
||||
this.rainfall = rainfall;
|
||||
this.temperature = temperature;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public BiomeData(String name, Object reference, int color, float rainfall, float temperature) {
|
||||
Color c = new Color(color);
|
||||
this.reference = reference;
|
||||
this.name = name;
|
||||
this.rainfall = rainfall;
|
||||
this.temperature = temperature;
|
||||
this.color = getHue(c.getRed(), c.getGreen(), c.getBlue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(BiomeData o) {
|
||||
return name.compareTo(o.name);
|
||||
}
|
||||
|
||||
public static Collection<BiomeData> getBiomes(float temperature, float rainfall) {
|
||||
int temp = Math.min(3, (int) (bounds.length * temperature));
|
||||
int rain = Math.min(3, (int) (bounds.length * rainfall));
|
||||
return getBiomes(temp, rain);
|
||||
}
|
||||
|
||||
public static Collection<BiomeData> getBiomes(int tempLower, int rainLower) {
|
||||
int temp0 = tempLower;
|
||||
int temp1 = temp0 + 1;
|
||||
int rain0 = rainLower;
|
||||
int rain1 = rain0 + 1;
|
||||
|
||||
float tempMin = bounds[temp0];
|
||||
float tempMax = bounds[temp1];
|
||||
float rainMin = bounds[rain0];
|
||||
float rainMax = bounds[rain1];
|
||||
|
||||
List<BiomeData> biomes = new ArrayList<>();
|
||||
for (BiomeData biome : BIOMES) {
|
||||
if (biome.temperature >= tempMin && biome.temperature <= tempMax
|
||||
&& biome.rainfall >= rainMin && biome.rainfall <= rainMax) {
|
||||
biomes.add(biome);
|
||||
}
|
||||
}
|
||||
|
||||
if (biomes.isEmpty()) {
|
||||
biomes.add(DEFAULT);
|
||||
}
|
||||
|
||||
return biomes;
|
||||
}
|
||||
|
||||
public static Collection<BiomeData> getTempBiomes(float temperature) {
|
||||
int lower = Math.min(3, (int) (bounds.length * temperature));
|
||||
int upper = lower + 1;
|
||||
|
||||
float min = bounds[lower];
|
||||
float max = bounds[upper];
|
||||
|
||||
List<BiomeData> biomes = new ArrayList<>();
|
||||
for (BiomeData data : BIOMES) {
|
||||
if (data.temperature >= min && data.temperature <= max) {
|
||||
biomes.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
return biomes;
|
||||
}
|
||||
|
||||
public static Collection<BiomeData> getRainBiomes(float rainfall) {
|
||||
int lower = Math.min(3, (int) (bounds.length * rainfall));
|
||||
int upper = lower + 1;
|
||||
|
||||
float min = bounds[lower];
|
||||
float max = bounds[upper];
|
||||
|
||||
List<BiomeData> biomes = new ArrayList<>();
|
||||
for (BiomeData data : BIOMES) {
|
||||
if (data.rainfall >= min && data.rainfall <= max) {
|
||||
biomes.add(data);
|
||||
}
|
||||
}
|
||||
|
||||
return biomes;
|
||||
}
|
||||
|
||||
private static float getHue(int red, int green, int blue) {
|
||||
float min = Math.min(Math.min(red, green), blue);
|
||||
float max = Math.max(Math.max(red, green), blue);
|
||||
|
||||
if (min == max) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
float hue;
|
||||
if (max == red) {
|
||||
hue = (green - blue) / (max - min);
|
||||
|
||||
} else if (max == green) {
|
||||
hue = 2f + (blue - red) / (max - min);
|
||||
|
||||
} else {
|
||||
hue = 4f + (red - green) / (max - min);
|
||||
}
|
||||
|
||||
hue = hue * 60;
|
||||
if (hue < 0) hue = hue + 360;
|
||||
|
||||
return (Math.round(hue) / 360F) * 100F;
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world.biome;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class BiomeManager {
|
||||
|
||||
private final Map<BiomeType, List<BiomeData>> biomes = new HashMap<>();
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world.biome;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import java.awt.*;
|
||||
|
||||
public enum BiomeType {
|
||||
|
||||
TROPICAL_RAINFOREST(7, 83, 48, new Color(7, 83, 48)),
|
||||
SAVANNA(151, 165, 39, new Color(151, 165, 39)),
|
||||
DESERT(200, 113, 55, new Color(200, 113, 55)),
|
||||
TEMPERATE_RAINFOREST(10, 84, 109, new Color(10, 160, 65)),
|
||||
TEMPERATE_FOREST(44, 137, 160, new Color(50, 200, 80)),
|
||||
GRASSLAND(179, 124, 6, new Color(100, 220, 60)),
|
||||
COLD_STEPPE(131, 112, 71, new Color(175, 180, 150)),
|
||||
STEPPE(199, 155, 60, new Color(200, 200, 120)),
|
||||
TAIGA(91, 143, 82, new Color(91, 143, 82)),
|
||||
TUNDRA(147, 167, 172, new Color(147, 167, 172)),
|
||||
ALPINE(0, 0, 0, new Color(160, 120, 170));
|
||||
|
||||
public static final int RESOLUTION = 256;
|
||||
public static final int MAX = RESOLUTION - 1;
|
||||
|
||||
private final Color lookup;
|
||||
private final Color color;
|
||||
|
||||
BiomeType(int r, int g, int b, Color color) {
|
||||
this(new Color(r, g, b), color);
|
||||
}
|
||||
|
||||
BiomeType(Color lookup, Color color) {
|
||||
this.lookup = lookup;
|
||||
this.color = BiomeTypeColors.getInstance().getColor(name(), color);
|
||||
}
|
||||
|
||||
Color getLookup() {
|
||||
return lookup;
|
||||
}
|
||||
|
||||
public Color getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public boolean isExtreme() {
|
||||
return this == TUNDRA || this == DESERT;
|
||||
}
|
||||
|
||||
public static BiomeType get(float temperature, float moisture) {
|
||||
return getCurve(temperature, moisture);
|
||||
}
|
||||
|
||||
public static BiomeType getLinear(float temperature, float moisture) {
|
||||
int x = NoiseUtil.round(MAX * temperature);
|
||||
int y = getYLinear(x, temperature, moisture);
|
||||
return getType(x, y);
|
||||
}
|
||||
|
||||
public static BiomeType getCurve(float temperature, float moisture) {
|
||||
int x = NoiseUtil.round(MAX * temperature);
|
||||
int y = getYCurve(x, temperature, moisture);
|
||||
return getType(x, y);
|
||||
}
|
||||
|
||||
public static float getEdge(float temperature, float moisture) {
|
||||
return getEdgeCurve(temperature, moisture);
|
||||
}
|
||||
|
||||
public static float getEdgeLinear(float temperature, float moisture) {
|
||||
int x = NoiseUtil.round(MAX * temperature);
|
||||
int y = getYLinear(x, temperature, moisture);
|
||||
return getEdge(x, y);
|
||||
}
|
||||
|
||||
public static float getEdgeCurve(float temperature, float moisture) {
|
||||
int x = NoiseUtil.round(MAX * temperature);
|
||||
int y = getYCurve(x, temperature, moisture);
|
||||
return getEdge(x, y);
|
||||
}
|
||||
|
||||
public static void apply(Cell<?> cell) {
|
||||
applyCurve(cell);
|
||||
}
|
||||
|
||||
public static void applyLinear(Cell<?> cell) {
|
||||
cell.biomeType = get(cell.biomeTemperature, cell.biomeMoisture);
|
||||
cell.biomeTypeMask = getEdge(cell.temperature, cell.moisture);
|
||||
}
|
||||
|
||||
public static void applyCurve(Cell<?> cell) {
|
||||
cell.biomeType = get(cell.biomeTemperature, cell.biomeMoisture);
|
||||
cell.biomeTypeMask = getEdge(cell.temperature, cell.moisture);
|
||||
}
|
||||
|
||||
private static BiomeType getType(int x, int y) {
|
||||
return BiomeTypeLoader.getInstance().getTypeMap()[y][x];
|
||||
}
|
||||
|
||||
private static float getEdge(int x, int y) {
|
||||
return BiomeTypeLoader.getInstance().getEdgeMap()[y][x];
|
||||
}
|
||||
|
||||
private static int getYLinear(int x, float temperature, float moisture) {
|
||||
if (moisture > temperature) {
|
||||
return x;
|
||||
}
|
||||
return NoiseUtil.round(MAX * moisture);
|
||||
}
|
||||
|
||||
private static int getYCurve(int x, float temperature, float moisture) {
|
||||
int max = x + ((MAX - x) / 2);
|
||||
int y = NoiseUtil.round(max * moisture);
|
||||
return Math.min(x, y);
|
||||
}
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world.biome;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class BiomeTypeColors {
|
||||
|
||||
private static BiomeTypeColors instance = new BiomeTypeColors();
|
||||
|
||||
private final Map<String, Color> colors = new HashMap<>();
|
||||
|
||||
private BiomeTypeColors() {
|
||||
try (InputStream inputStream = BiomeType.class.getResourceAsStream("/biomes.txt")) {
|
||||
Properties properties = new Properties();
|
||||
properties.load(inputStream);
|
||||
for (Map.Entry<?, ?> entry : properties.entrySet()) {
|
||||
Color color = Color.decode("#" + entry.getValue().toString());
|
||||
colors.put(entry.getKey().toString(), color);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Color getColor(String name, Color defaultColor) {
|
||||
return colors.getOrDefault(name, defaultColor);
|
||||
}
|
||||
|
||||
public static BiomeTypeColors getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
try (FileWriter writer = new FileWriter("biome_colors.properties")) {
|
||||
Properties properties = new Properties();
|
||||
for (BiomeType type : BiomeType.values()) {
|
||||
int r = type.getColor().getRed();
|
||||
int g = type.getColor().getGreen();
|
||||
int b = type.getColor().getBlue();
|
||||
properties.setProperty(type.name(), String.format("%02x%02x%02x", r, g, b));
|
||||
}
|
||||
properties.store(writer, "TerraForged BiomeType Hex Colors (do not include hash/pound character)");
|
||||
}
|
||||
}
|
||||
}
|
@ -1,204 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world.biome;
|
||||
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class BiomeTypeLoader {
|
||||
|
||||
private static BiomeTypeLoader instance;
|
||||
|
||||
private final float[][] edges = new float[BiomeType.RESOLUTION][BiomeType.RESOLUTION];
|
||||
private final BiomeType[][] map = new BiomeType[BiomeType.RESOLUTION][BiomeType.RESOLUTION];
|
||||
|
||||
public BiomeTypeLoader() {
|
||||
generateTypeMap();
|
||||
generateEdgeMap();
|
||||
}
|
||||
|
||||
public BiomeType[][] getTypeMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public float[][] getEdgeMap() {
|
||||
return edges;
|
||||
}
|
||||
|
||||
private BiomeType getType(int x, int y) {
|
||||
return map[y][x];
|
||||
}
|
||||
|
||||
private void generateTypeMap() {
|
||||
try {
|
||||
BufferedImage image = ImageIO.read(BiomeType.class.getResourceAsStream("/biomes.png"));
|
||||
float xf = image.getWidth() / (float) BiomeType.RESOLUTION;
|
||||
float yf = image.getHeight() / (float) BiomeType.RESOLUTION;
|
||||
for (int y = 0; y < BiomeType.RESOLUTION; y++) {
|
||||
for (int x = 0; x < BiomeType.RESOLUTION; x++) {
|
||||
if (BiomeType.MAX - y > x) {
|
||||
map[BiomeType.MAX - y][x] = BiomeType.ALPINE;
|
||||
continue;
|
||||
}
|
||||
int ix = NoiseUtil.round(x * xf);
|
||||
int iy = NoiseUtil.round(y * yf);
|
||||
int argb = image.getRGB(ix, iy);
|
||||
Color color = fromARGB(argb);
|
||||
map[BiomeType.MAX - y][x] = forColor(color);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateEdgeMap() {
|
||||
int[] distances = new int[BiomeType.values().length];
|
||||
for (int y = 0; y < BiomeType.RESOLUTION; y++) {
|
||||
for (int x = 0; x < BiomeType.RESOLUTION; x++) {
|
||||
if (y > x) continue;
|
||||
BiomeType type = getType(x, y);
|
||||
if (type == BiomeType.ALPINE) {
|
||||
continue;
|
||||
}
|
||||
int distance2 = getEdge(x, y, type);
|
||||
edges[y][x] = distance2;
|
||||
distances[type.ordinal()] = Math.max(distances[type.ordinal()], distance2);
|
||||
}
|
||||
}
|
||||
|
||||
for (int y = 0; y < BiomeType.RESOLUTION; y++) {
|
||||
for (int x = 0; x < BiomeType.RESOLUTION; x++) {
|
||||
BiomeType type = getType(x, y);
|
||||
int max = distances[type.ordinal()];
|
||||
float distance = edges[y][x];
|
||||
float value = NoiseUtil.pow(distance / max, 0.33F);
|
||||
edges[y][x] = NoiseUtil.clamp(value, 0, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getEdge(int cx, int cy, BiomeType type) {
|
||||
int radius = BiomeType.RESOLUTION / 4;
|
||||
int distance2 = Integer.MAX_VALUE;
|
||||
int x0 = Math.max(0, cx - radius);
|
||||
int x1 = Math.min(BiomeType.MAX, cx + radius);
|
||||
int y0 = Math.max(0, cy - radius);
|
||||
int y1 = Math.min(BiomeType.MAX, cy + radius);
|
||||
for (int y = y0; y <= y1; y++) {
|
||||
for (int x = x0; x <= x1; x++) {
|
||||
BiomeType neighbour = getType(x, y);
|
||||
|
||||
if (neighbour == BiomeType.ALPINE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (neighbour != type) {
|
||||
int dist2 = dist2(cx, cy, x, y);
|
||||
if (dist2 < distance2) {
|
||||
distance2 = dist2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return distance2;
|
||||
}
|
||||
|
||||
private static BiomeType forColor(Color color) {
|
||||
BiomeType type = null;
|
||||
int closest = Integer.MAX_VALUE;
|
||||
for (BiomeType t : BiomeType.values()) {
|
||||
int distance2 = getDistance2(color, t.getLookup());
|
||||
if (distance2 < closest) {
|
||||
closest = distance2;
|
||||
type = t;
|
||||
}
|
||||
}
|
||||
if (type == null) {
|
||||
return BiomeType.GRASSLAND;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static int getDistance2(Color a, Color b) {
|
||||
int dr = a.getRed() - b.getRed();
|
||||
int dg = a.getGreen() - b.getGreen();
|
||||
int db = a.getBlue() - b.getBlue();
|
||||
return dr * dr + dg * dg + db * db;
|
||||
}
|
||||
|
||||
private static Color fromARGB(int argb) {
|
||||
int b = (argb) & 0xFF;
|
||||
int g = (argb >> 8) & 0xFF;
|
||||
int r = (argb >> 16) & 0xFF;
|
||||
return new Color(r, g, b);
|
||||
}
|
||||
|
||||
private static int dist2(int x1, int y1, int x2, int y2) {
|
||||
int dx = x1 - x2;
|
||||
int dy = y1 - y2;
|
||||
return dx * dx + dy * dy;
|
||||
}
|
||||
|
||||
private static BufferedImage generateEdgeMapImage() {
|
||||
BufferedImage image = new BufferedImage(BiomeType.RESOLUTION, BiomeType.RESOLUTION, BufferedImage.TYPE_INT_RGB);
|
||||
for (int y = 0; y < BiomeType.RESOLUTION; y++) {
|
||||
for (int x = 0; x < BiomeType.RESOLUTION; x++) {
|
||||
float temperature = x / (float) BiomeType.RESOLUTION;
|
||||
float moisture = y / (float) BiomeType.RESOLUTION;
|
||||
float value = BiomeType.getEdge(temperature, moisture);
|
||||
int color = Color.HSBtoRGB(0, 0, value);
|
||||
image.setRGB(x, image.getHeight() - 1 - y, color);
|
||||
}
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
public static BiomeTypeLoader getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new BiomeTypeLoader();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
BufferedImage img = generateEdgeMapImage();
|
||||
ImageIO.write(img, "png", new File("biomes_dist.png"));
|
||||
JLabel label = new JLabel(new ImageIcon(img));
|
||||
JFrame frame = new JFrame();
|
||||
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
frame.add(label);
|
||||
frame.pack();
|
||||
frame.setLocationRelativeTo(null);
|
||||
frame.setVisible(true);
|
||||
}
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world.climate;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.world.GeneratorContext;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.Source;
|
||||
import me.dags.noise.source.Rand;
|
||||
|
||||
public class Climate {
|
||||
|
||||
private final float seaLevel;
|
||||
private final float lowerHeight;
|
||||
private final float midHeight = 0.45F;
|
||||
private final float upperHeight = 0.75F;
|
||||
|
||||
private final float moistureModifier = 0.1F;
|
||||
private final float temperatureModifier = 0.05F;
|
||||
|
||||
private final Rand rand;
|
||||
private final Module treeLine;
|
||||
private final Module offsetX;
|
||||
private final Module offsetY;
|
||||
|
||||
private final ClimateModule biomeNoise;
|
||||
|
||||
public Climate(GeneratorContext context) {
|
||||
this.biomeNoise = new ClimateModule(context.seed, context.settings);
|
||||
|
||||
this.treeLine = Source.perlin(context.seed.next(), context.settings.generator.biome.biomeSize * 2, 1)
|
||||
.scale(context.levels.scale(25)) // 30 units worth of variance
|
||||
.bias(context.levels.ground(40)) // start at-least 30 units above ground level
|
||||
.clamp(0, 1);
|
||||
|
||||
this.rand = new Rand(Source.builder().seed(context.seed.next()));
|
||||
this.offsetX = context.settings.generator.biomeEdgeNoise.build(context.seed.next());
|
||||
this.offsetY = context.settings.generator.biomeEdgeNoise.build(context.seed.next());
|
||||
this.seaLevel = context.levels.water;
|
||||
this.lowerHeight = context.levels.ground;
|
||||
}
|
||||
|
||||
public Rand getRand() {
|
||||
return rand;
|
||||
}
|
||||
|
||||
public float getOffsetX(float x, float z, int distance) {
|
||||
return offsetX.getValue(x, z) * distance;
|
||||
}
|
||||
|
||||
public float getOffsetZ(float x, float z, int distance) {
|
||||
return offsetY.getValue(x, z) * distance;
|
||||
}
|
||||
|
||||
public float getTreeLine(float x, float z) {
|
||||
return treeLine.getValue(x, z);
|
||||
}
|
||||
|
||||
public void apply(Cell<Terrain> cell, float x, float z, boolean mask) {
|
||||
biomeNoise.apply(cell, x, z, mask);
|
||||
|
||||
modifyTemp(cell, x, z);
|
||||
}
|
||||
|
||||
private void modifyTemp(Cell<Terrain> cell, float x, float z) {
|
||||
float height = cell.value;
|
||||
if (height > upperHeight) {
|
||||
cell.temperature = Math.max(0, cell.temperature - temperatureModifier);
|
||||
return;
|
||||
}
|
||||
|
||||
// temperature decreases away from 'midHeight' towards 'upperHeight'
|
||||
if (height > midHeight) {
|
||||
float delta = (height - midHeight) / (upperHeight - midHeight);
|
||||
cell.temperature = Math.max(0, cell.temperature - (delta * temperatureModifier));
|
||||
return;
|
||||
}
|
||||
|
||||
height = Math.max(lowerHeight, height);
|
||||
|
||||
// temperature increases away from 'midHeight' towards 'lowerHeight'
|
||||
if (height >= lowerHeight) {
|
||||
float delta = 1 - ((height - lowerHeight) / (midHeight - lowerHeight));
|
||||
cell.temperature = Math.min(1, cell.temperature + (delta * temperatureModifier));
|
||||
}
|
||||
}
|
||||
}
|
@ -1,166 +0,0 @@
|
||||
/*
|
||||
*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2020 TerraForged
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package com.terraforged.core.world.climate;
|
||||
|
||||
import com.terraforged.core.cell.Cell;
|
||||
import com.terraforged.core.settings.Settings;
|
||||
import com.terraforged.core.util.Seed;
|
||||
import com.terraforged.core.world.biome.BiomeType;
|
||||
import com.terraforged.core.world.terrain.Terrain;
|
||||
import me.dags.noise.Module;
|
||||
import me.dags.noise.Source;
|
||||
import me.dags.noise.func.DistanceFunc;
|
||||
import me.dags.noise.func.EdgeFunc;
|
||||
import me.dags.noise.util.NoiseUtil;
|
||||
import me.dags.noise.util.Vec2f;
|
||||
|
||||
public class ClimateModule {
|
||||
|
||||
private final int seed;
|
||||
|
||||
private final float edgeClamp;
|
||||
private final float edgeScale;
|
||||
private final float biomeFreq;
|
||||
private final float warpStrength;
|
||||
|
||||
private final Module warpX;
|
||||
private final Module warpZ;
|
||||
private final Module moisture;
|
||||
private final Module temperature;
|
||||
|
||||
public ClimateModule(Seed seed, Settings settings) {
|
||||
int biomeSize = settings.generator.biome.biomeSize;
|
||||
|
||||
// todo - better solution (reduces the amount that temp/moist grows with biome size)
|
||||
int tempScaler = biomeSize > 500 ? 8 : 10;
|
||||
int moistScaler = biomeSize > 500 ? 20 : 40;
|
||||
|
||||
float biomeFreq = 1F / biomeSize;
|
||||
int moistureSize = moistScaler * biomeSize;
|
||||
int temperatureSize = tempScaler * biomeSize;
|
||||
int moistScale = NoiseUtil.round(moistureSize * biomeFreq);
|
||||
int tempScale = NoiseUtil.round(temperatureSize * biomeFreq);
|
||||
int warpScale = settings.generator.biome.biomeWarpScale;
|
||||
|
||||
this.seed = seed.next();
|
||||
this.edgeClamp = 1F;
|
||||
this.edgeScale = 1 / edgeClamp;
|
||||
this.biomeFreq = 1F / biomeSize;
|
||||
this.warpStrength = settings.generator.biome.biomeWarpStrength;
|
||||
this.warpX = Source.perlin(seed.next(), warpScale, 2).bias(-0.5);
|
||||
this.warpZ = Source.perlin(seed.next(), warpScale, 2).bias(-0.5);
|
||||
|
||||
Module moisture = Source.simplex(seed.next(), moistScale, 2).clamp(0.15, 0.85).map(0, 1);
|
||||
this.moisture = settings.climate.moisture.clamp(moisture)
|
||||
.warp(seed.next(), moistScale / 2, 1, moistScale / 4D)
|
||||
.warp(seed.next(), moistScale / 6, 2, moistScale / 12D);
|
||||
|
||||
Module temperature = Source.sin(tempScale, Source.constant(0.9))
|
||||
.clamp(0.05, 0.95).map(0, 1);
|
||||
|
||||
this.temperature = new Compressor(settings.climate.temperature.clamp(temperature), 0.1F, 0.2F)
|
||||
.warp(seed.next(), tempScale * 4, 2, tempScale * 4)
|
||||
.warp(seed.next(), tempScale, 1, tempScale)
|
||||
.warp(seed.next(), tempScale / 8, 1, tempScale / 8D);
|
||||
}
|
||||
|
||||
public void apply(Cell<Terrain> cell, float x, float y, boolean mask) {
|
||||
float ox = warpX.getValue(x, y) * warpStrength;
|
||||
float oz = warpZ.getValue(x, y) * warpStrength;
|
||||
|
||||
x += ox;
|
||||
y += oz;
|
||||
|
||||
x *= biomeFreq;
|
||||
y *= biomeFreq;
|
||||
|
||||
int cellX = 0;
|
||||
int cellY = 0;
|
||||
|
||||
Vec2f vec2f = null;
|
||||
int xr = NoiseUtil.round(x);
|
||||
int yr = NoiseUtil.round(y);
|
||||
float edgeDistance = 999999.0F;
|
||||
float edgeDistance2 = 999999.0F;
|
||||
float valueDistance = 3.4028235E38F;
|
||||
DistanceFunc dist = DistanceFunc.NATURAL;
|
||||
|
||||
for (int dy = -1; dy <= 1; dy++) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
int xi = xr + dx;
|
||||
int yi = yr + dy;
|
||||
Vec2f vec = NoiseUtil.CELL_2D[NoiseUtil.hash2D(seed, xi, yi) & 255];
|
||||
|
||||
float vecX = xi - x + vec.x;
|
||||
float vecY = yi - y + vec.y;
|
||||
float distance = dist.apply(vecX, vecY);
|
||||
|
||||
if (distance < valueDistance) {
|
||||
valueDistance = distance;
|
||||
vec2f = vec;
|
||||
cellX = xi;
|
||||
cellY = yi;
|
||||
}
|
||||
|
||||
if (distance < edgeDistance2) {
|
||||
edgeDistance2 = Math.max(edgeDistance, distance);
|
||||
} else {
|
||||
edgeDistance2 = Math.max(edgeDistance, edgeDistance2);
|
||||
}
|
||||
|
||||
edgeDistance = Math.min(edgeDistance, distance);
|
||||
}
|
||||
}
|
||||
|
||||
if (mask) {
|
||||
cell.biomeEdge = edgeValue(edgeDistance, edgeDistance2);
|
||||
} else {
|
||||
cell.biome = cellValue(seed, cellX, cellY);
|
||||
cell.biomeEdge = edgeValue(edgeDistance, edgeDistance2);
|
||||
cell.biomeMoisture = moisture.getValue(cellX + vec2f.x, cellY + vec2f.y);
|
||||
cell.biomeTemperature = temperature.getValue(cellX + vec2f.x, cellY + vec2f.y);
|
||||
cell.moisture = moisture.getValue(x, y);
|
||||
cell.temperature = temperature.getValue(x, y);
|
||||
|
||||
BiomeType.apply(cell);
|
||||
}
|
||||
}
|
||||
|
||||
private float cellValue(int seed, int cellX, int cellY) {
|
||||
float value = NoiseUtil.valCoord2D(seed, cellX, cellY);
|
||||
return NoiseUtil.map(value, -1, 1, 2);
|
||||
}
|
||||
|
||||
private float edgeValue(float distance, float distance2) {
|
||||
EdgeFunc edge = EdgeFunc.DISTANCE_2_DIV;
|
||||
float value = edge.apply(distance, distance2);
|
||||
value = 1 - NoiseUtil.map(value, edge.min(), edge.max(), edge.range());
|
||||
if (value > edgeClamp) {
|
||||
return 1F;
|
||||
}
|
||||
return value * edgeScale;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user