Update configs for lighting changes and finalize ui

This commit is contained in:
Blue (Lukas Rieger) 2020-03-08 20:56:52 +01:00
parent ba2092b614
commit 80f1d90cdf
37 changed files with 414 additions and 387 deletions

View File

@ -3,6 +3,7 @@ metrics: true
renderThreadCount: -2
data: "bluemap"
webroot: "bluemap/web"
useCookies: true
webserver {
enabled: true
port: 8100

View File

@ -37,6 +37,9 @@ webroot: "bluemap/web"
# Default is "<webroot>/data"
#webdata: "path/to/data/folder"
# If the web-application should use cookies to save the configurations of a user.
useCookies: true
webserver {
# With this setting you can disable the integrated web-server.
# This is usefull if you want to only render the map-data for later use, or if you setup your own webserver.
@ -65,40 +68,43 @@ maps: [
{
# The id of this map
# Should only contain word-charactes: [a-zA-Z0-9_]
# Changing this value breaks your existing renders.
id: "world"
# The name of this map
# This defines the display name of this map, you can change this at any time
# This defines the display name of this map, you can change this at any time.
# Default is the id of this map
name: "World"
# The path to the save-folder of the world to render
# The path to the save-folder of the world to render.
world: "world"
# The position on the world where the map will be centered if you open it.
# You can change this at any time.
# This defaults to the world-spawn if you don't set it.
#startPos: [500, -820]
# The color of thy sky as a hex-color
# You can change this at any time.
# Default is "#7dabff"
skyColor: "#7dabff"
# Defines the ambient light-strength that every block is recieving, regardless of the sunlight/blocklight.
# 0 is no ambient light, 1 is fully lighted.
# You can change this at any time.
# Default is 0
ambientLight: 0
# If this is false, BlueMap tries to omit all blocks that are not visible from above-ground.
# More specific: Block-Faces that have a sunlight/skylight value of 0 are removed.
# This improves the performance of the map on slower devices by a lot, but might cause some blocks to disappear that should normally be visible.
# Changing this value requires a re-render of the map.
# Default is false
renderCaves: false
# AmbientOcclusion adds soft shadows into corners, which gives the map a much better look.
# This has only a small impact on render-time and has no impact on the web-performance of the map.
# The value defines the strength of the shading, a value of 0 disables ambientOcclusion.
# Default is 0.25
ambientOcclusion: 0.25
# Lighting uses the light-data in minecraft to shade each block-face.
# If this is enabled, caves and inside buildings without torches will be darker.
# The value defines the strength of the shading and a value of 0 disables lighting (every block will be fully lit).
# Default is 0.8
lighting: 0.8
# With the below values you can limit the map-render.
# This can be used to ignore the nethers ceiling or render only a certain part of a world.
# Changing this values might require a re-render of the map, already rendered tiles outside the limits will not be deleted.
# Default is no min or max value (= infinite bounds)
#minX: -4000
#maxX: 4000
@ -110,43 +116,17 @@ maps: [
# Using this, BlueMap pretends that every Block out of the defined render-bounds is AIR,
# this means you can see the blocks where the world is cut (instead of having a see-through/xray view).
# This has only an effect if you set some render-bounds above.
# Default is enabled
# Changing this value requires a re-render of the map.
# Default is true
renderEdges: true
# With this set to true, the generated files for this world are compressed using gzip to save A LOT of space.
# Files will be only 5% as big with compression!
# Note: If you are using NGINX or Apache to host your map, you can configure them to serve the compressed files directly.
# This is much better than disabling the compression.
# Changing this value requires a re-render of the map.
# Default is true
useCompression: true
# HIRES is the high-resolution render of the map. Where you see every block.
hires {
# Defines the size of one map-tile in blocks.
# If you change this value, the lowres values might need adjustment as well!
# Default is 32
tileSize: 32
# The View-Distance for hires tiles on the web-map (the value is the radius in tiles)
# Default is 4.5
viewDistance: 4.5
}
# LOWRES is the low-resolution render of the map. Thats the model that you see if you zoom far out to get an overview.
lowres {
# Defines resolution of the lowres model. E.g. If the hires.tileSize is 32, a value of 4 means that every 8*8 blocks will be summarized by one point on the lowres map.
# Calculation: 32 / 4 = 8
# You can only use values that result in an integer if you use the above calculation!
# Default is 4
pointsPerHiresTile: 4
# Defines the size of one lowres-map-tile in points.
# Default is 50
pointsPerLowresTile: 50
# The View-Distance for lowres tiles on the web-map (the value is the radius in tiles)
# Default is 7
viewDistance: 7
}
}
# Here another example for the End-Map
@ -154,23 +134,23 @@ maps: [
{
id: "end"
name: "End"
world: "world/DIM1"
world: "world_the_end"
# In the end is no sky-light, so we need to enable this or we won't see anything.
renderCaves: true
# Same here, we don't want a dark map. But not completely disabled, so we see the effect of e.g torches.
lighting: 0.4
# Same here, we don't want a dark map. But not completely lighted, so we see the effect of e.g torches.
ambientLight: 0.6
}
# Here another example for the Nether-Map
{
id: "nether"
name: "Nether"
world: "world/DIM-1"
world: "world_nether"
renderCaves: true
lighting: 0.6
ambientLight: 0.6
# We slice the whole world at y:90 so every block above 90 will be air.
# This way we don't render the nethers ceiling.

View File

@ -141,9 +141,10 @@ public void renderMaps() throws IOException {
Logger.global.logInfo("Writing settings.json ...");
WebSettings webSettings = new WebSettings(config.getWebDataPath().resolve("settings.json").toFile());
webSettings.setAllEnabled(false);
webSettings.set(config.isUseCookies(), "useCookies");
webSettings.setAllMapsEnabled(false);
for (MapType map : maps.values()) {
webSettings.setEnabled(true, map.getId());
webSettings.setMapEnabled(true, map.getId());
webSettings.setFrom(map.getTileRenderer(), map.getId());
webSettings.setFrom(map.getWorld(), map.getId());
}

View File

@ -2,7 +2,8 @@ accept-download: false
metrics: true
renderThreadCount: 0
data: "."
webroot: "web"
webroot: "web"
useCookies: true
webserver {
enabled: false
port: 8100

View File

@ -37,6 +37,9 @@ webroot: "web"
# Default is "<webroot>/data"
#webdata: "path/to/data/folder"
# If the web-application should use cookies to save the configurations of a user.
useCookies: true
webserver {
# With this setting you can enable the integrated web-server.
# Default is disabled
@ -64,40 +67,43 @@ maps: [
{
# The id of this map
# Should only contain word-charactes: [a-zA-Z0-9_]
# Changing this value breaks your existing renders.
id: "world"
# The name of this map
# This defines the display name of this map, you can change this at any time
# This defines the display name of this map, you can change this at any time.
# Default is the id of this map
name: "World"
# The path to the save-folder of the world to render
# The path to the save-folder of the world to render.
world: "world"
# The position on the world where the map will be centered if you open it.
# You can change this at any time.
# This defaults to the world-spawn if you don't set it.
#startPos: [500, -820]
# The color of thy sky as a hex-color
# You can change this at any time.
# Default is "#7dabff"
skyColor: "#7dabff"
# Defines the ambient light-strength that every block is recieving, regardless of the sunlight/blocklight.
# 0 is no ambient light, 1 is fully lighted.
# You can change this at any time.
# Default is 0
ambientLight: 0
# If this is false, BlueMap tries to omit all blocks that are not visible from above-ground.
# More specific: Block-Faces that have a sunlight/skylight value of 0 are removed.
# This improves the performance of the map on slower devices by a lot, but might cause some blocks to disappear that should normally be visible.
# Changing this value requires a re-render of the map.
# Default is false
renderCaves: false
# AmbientOcclusion adds soft shadows into corners, which gives the map a much better look.
# This has only a small impact on render-time and has no impact on the web-performance of the map.
# The value defines the strength of the shading, a value of 0 disables ambientOcclusion.
# Default is 0.25
ambientOcclusion: 0.25
# Lighting uses the light-data in minecraft to shade each block-face.
# If this is enabled, caves and inside buildings without torches will be darker.
# The value defines the strength of the shading and a value of 0 disables lighting (every block will be fully lit).
# Default is 0.8
lighting: 0.8
# With the below values you can limit the map-render.
# This can be used to ignore the nethers ceiling or render only a certain part of a world.
# Changing this values might require a re-render of the map, already rendered tiles outside the limits will not be deleted.
# Default is no min or max value (= infinite bounds)
#minX: -4000
#maxX: 4000
@ -109,43 +115,17 @@ maps: [
# Using this, BlueMap pretends that every Block out of the defined render-bounds is AIR,
# this means you can see the blocks where the world is cut (instead of having a see-through/xray view).
# This has only an effect if you set some render-bounds above.
# Default is enabled
# Changing this value requires a re-render of the map.
# Default is true
renderEdges: true
# With this set to true, the generated files for this world are compressed using gzip to save A LOT of space.
# Files will be only 5% as big with compression!
# Note: If you are using NGINX or Apache to host your map, you can configure them to serve the compressed files directly.
# This is much better than disabling the compression.
# Changing this value requires a re-render of the map.
# Default is true
useCompression: true
# HIRES is the high-resolution render of the map. Where you see every block.
hires {
# Defines the size of one map-tile in blocks.
# If you change this value, the lowres values might need adjustment as well!
# Default is 32
tileSize: 32
# The View-Distance for hires tiles on the web-map (the value is the radius in tiles)
# Default is 4.5
viewDistance: 4.5
}
# LOWRES is the low-resolution render of the map. Thats the model that you see if you zoom far out to get an overview.
lowres {
# Defines resolution of the lowres model. E.g. If the hires.tileSize is 32, a value of 4 means that every 8*8 blocks will be summarized by one point on the lowres map.
# Calculation: 32 / 4 = 8
# You can only use values that result in an integer if you use the above calculation!
# Default is 4
pointsPerHiresTile: 4
# Defines the size of one lowres-map-tile in points.
# Default is 50
pointsPerLowresTile: 50
# The View-Distance for lowres tiles on the web-map (the value is the radius in tiles)
# Default is 7
viewDistance: 7
}
}
# Here another example for the End-Map
@ -158,8 +138,8 @@ maps: [
# In the end is no sky-light, so we need to enable this or we won't see anything.
renderCaves: true
# Same here, we don't want a dark map. But not completely disabled, so we see the effect of e.g torches.
lighting: 0.4
# Same here, we don't want a dark map. But not completely lighted, so we see the effect of e.g torches.
ambientLight: 0.6
}
# Here another example for the Nether-Map
@ -169,7 +149,7 @@ maps: [
world: "world/DIM-1"
renderCaves: true
lighting: 0.6
ambientLight: 0.6
# We slice the whole world at y:90 so every block above 90 will be air.
# This way we don't render the nethers ceiling.

View File

@ -246,9 +246,10 @@ public synchronized void load() throws IOException, ParseResourceException {
}
WebSettings webSettings = new WebSettings(config.getWebDataPath().resolve("settings.json").toFile());
webSettings.setAllEnabled(false);
webSettings.set(config.isUseCookies(), "useCookies");
webSettings.setAllMapsEnabled(false);
for (MapType map : maps.values()) {
webSettings.setEnabled(true, map.getId());
webSettings.setMapEnabled(true, map.getId());
webSettings.setFrom(map.getTileRenderer(), map.getId());
webSettings.setFrom(map.getWorld(), map.getId());
}

View File

@ -42,8 +42,6 @@
import ninja.leaping.configurate.ConfigurationNode;
public class MainConfig implements WebServerConfig {
private String version;
private boolean downloadAccepted = false;
private boolean metricsEnabled = false;
@ -52,6 +50,7 @@ public class MainConfig implements WebServerConfig {
private int webserverPort = 8100;
private int webserverMaxConnections = 100;
private InetAddress webserverBindAdress = null;
private boolean useCookies;
private Path dataPath = Paths.get("data");
@ -92,6 +91,8 @@ public MainConfig(ConfigurationNode node) throws OutdatedConfigException, IOExce
else
webDataPath = webRoot.resolve("data");
useCookies = node.getNode("useCookies").getBoolean(true);
//webserver
loadWebConfig(node.getNode("webserver"));
@ -137,14 +138,24 @@ private Path toFolder(String pathString) throws IOException {
return file.toPath();
}
@Override
public Path getWebRoot() {
return webRoot;
}
public Path getDataPath() {
return dataPath;
}
public boolean isUseCookies() {
return useCookies;
}
public boolean isWebserverEnabled() {
return webserverEnabled;
}
public Path getWebDataPath() {
return webDataPath;
}
@ -163,15 +174,6 @@ public int getWebserverMaxConnections() {
public InetAddress getWebserverBindAdress() {
return webserverBindAdress;
}
@Override
public Path getWebRoot() {
return webRoot;
}
public String getVersion() {
return version;
}
public boolean isDownloadAccepted() {
return downloadAccepted;
@ -196,10 +198,10 @@ public class MapConfig implements RenderSettings {
private String world;
private Vector2i startPos;
private int skyColor;
private float ambientLight;
private boolean renderCaves;
private float ambientOcclusion;
private float lighting;
private Vector3i min, max;
private boolean renderEdges;
@ -207,11 +209,9 @@ public class MapConfig implements RenderSettings {
private boolean useGzip;
private int hiresTileSize;
private float hiresViewDistance;
private int lowresPointsPerHiresTile;
private int lowresPointsPerLowresTile;
private float lowresViewDistance;
private MapConfig(ConfigurationNode node) throws IOException {
this.id = node.getNode("id").getString("");
@ -224,9 +224,12 @@ private MapConfig(ConfigurationNode node) throws IOException {
if (!node.getNode("startPos").isVirtual()) this.startPos = ConfigUtils.readVector2i(node.getNode("startPos"));
if (!node.getNode("skyColor").isVirtual()) this.skyColor = ConfigUtils.readColorInt(node.getNode("skyColor"));
else this.skyColor = 0x7dabff;
this.ambientLight = node.getNode("ambientLight").getFloat(0f);
this.renderCaves = node.getNode("renderCaves").getBoolean(false);
this.ambientOcclusion = node.getNode("ambientOcclusion").getFloat(0.25f);
this.lighting = node.getNode("lighting").getFloat(0.8f);
int minX = node.getNode("minX").getInt(RenderSettings.super.getMin().getX());
int maxX = node.getNode("maxX").getInt(RenderSettings.super.getMax().getX());
@ -242,11 +245,9 @@ private MapConfig(ConfigurationNode node) throws IOException {
this.useGzip = node.getNode("useCompression").getBoolean(true);
this.hiresTileSize = node.getNode("hires", "tileSize").getInt(32);
this.hiresViewDistance = node.getNode("hires", "viewDistance").getFloat(4.5f);
this.lowresPointsPerHiresTile = node.getNode("lowres", "pointsPerHiresTile").getInt(4);
this.lowresPointsPerLowresTile = node.getNode("lowres", "pointsPerLowresTile").getInt(50);
this.lowresViewDistance = node.getNode("lowres", "viewDistance").getFloat(7f);
//check valid configuration values
double blocksPerPoint = (double) this.hiresTileSize / (double) this.lowresPointsPerHiresTile;
@ -268,29 +269,23 @@ public String getWorldPath() {
public Vector2i getStartPos() {
return startPos;
}
public int getSkyColor() {
return skyColor;
}
public float getAmbientLight() {
return ambientLight;
}
public boolean isRenderCaves() {
return renderCaves;
}
@Override
public float getAmbientOcclusionStrenght() {
return ambientOcclusion;
}
@Override
public float getLightShadeMultiplier() {
return lighting;
}
public int getHiresTileSize() {
return hiresTileSize;
}
public float getHiresViewDistance() {
return hiresViewDistance;
}
public int getLowresPointsPerHiresTile() {
return lowresPointsPerHiresTile;
}
@ -299,10 +294,6 @@ public int getLowresPointsPerLowresTile() {
return lowresPointsPerLowresTile;
}
public float getLowresViewDistance() {
return lowresViewDistance;
}
@Override
public boolean isExcludeFacesWithoutSunlight() {
return !isRenderCaves();

View File

@ -30,15 +30,6 @@ public interface RenderSettings {
static final Vector3i DEFAULT_MIN = Vector3i.from(Integer.MIN_VALUE);
static final Vector3i DEFAULT_MAX = Vector3i.from(Integer.MAX_VALUE);
/**
* The strenght of ao-shading calculated for each vertex.<br>
* A value of 0 turns off ao.<br>
* The value represents the amount that each occluding face subtracts of the light-multiplier. (There are at most 3 occluding faces)
*/
default float getAmbientOcclusionStrenght() {
return 0.25f;
}
/**
* Whether faces that have a sky-light-value of 0 will be rendered or not.
@ -46,14 +37,6 @@ default float getAmbientOcclusionStrenght() {
default boolean isExcludeFacesWithoutSunlight() {
return true;
}
/**
* A multiplier to how much faces are shaded due to their light value<br>
* This can be used to make sure blocks with a light value of 0 are not pitch black
*/
default float getLightShadeMultiplier() {
return 0.8f;
}
/**
* The minimum position of blocks to render
@ -87,9 +70,7 @@ default boolean useGzipCompression() {
default RenderSettings copy() {
return new StaticRenderSettings(
getAmbientOcclusionStrenght(),
isExcludeFacesWithoutSunlight(),
getLightShadeMultiplier(),
getMin(),
getMax(),
isRenderEdges()

View File

@ -28,42 +28,26 @@
public class StaticRenderSettings implements RenderSettings {
private float ambientOcclusion;
private boolean excludeFacesWithoutSunlight;
private float lightShade;
private Vector3i min, max;
private boolean renderEdges;
public StaticRenderSettings(
float ambientOcclusion,
boolean excludeFacesWithoutSunlight,
float ligheShade,
Vector3i min,
Vector3i max,
boolean renderEdges
) {
this.ambientOcclusion = ambientOcclusion;
this.excludeFacesWithoutSunlight = excludeFacesWithoutSunlight;
this.lightShade = ligheShade;
this.min = min;
this.max = max;
this.renderEdges = renderEdges;
}
@Override
public float getAmbientOcclusionStrenght() {
return ambientOcclusion;
}
@Override
public boolean isExcludeFacesWithoutSunlight() {
return excludeFacesWithoutSunlight;
}
@Override
public float getLightShadeMultiplier() {
return lightShade;
}
@Override
public Vector3i getMin() {

View File

@ -209,9 +209,9 @@ private void createElementFace(ExtendedModel model, Direction faceDir, Vector3f
ExtendedFace f1 = new ExtendedFace(c0, c1, c2, uvs[0], uvs[1], uvs[2], textureId);
ExtendedFace f2 = new ExtendedFace(c0, c2, c3, uvs[0], uvs[2], uvs[3], textureId);
//move face in a tiny bit to avoid z-fighting with waterlogged blocks
f1.translate(faceDir.opposite().toVector().toFloat().mul(0.01));
f2.translate(faceDir.opposite().toVector().toFloat().mul(0.01));
// move face in a tiny bit to avoid z-fighting with waterlogged blocks (doesn't work because it is rounded back when storing the model later)
//f1.translate(faceDir.opposite().toVector().toFloat().mul(0.01));
//f2.translate(faceDir.opposite().toVector().toFloat().mul(0.01));
float blockLight = bl.getBlockLightLevel();
float sunLight = bl.getSunLightLevel();

View File

@ -326,7 +326,7 @@ private float testAo(Vector2f modelRotation, Vector3f vertex, Direction dir){
if (occluding > 3)
occluding = 3;
return Math.max(0f, Math.min(1f - (occluding * renderSettings.getAmbientOcclusionStrenght()), 1f));
return Math.max(0f, Math.min(1f - occluding * 0.25f, 1f));
}
private Vector2f[] rotateUVInner(Vector2f[] uv, int angle){

View File

@ -76,7 +76,7 @@ public LowresModelManager(Path fileRoot, Vector2i gridSize, Vector2i pointsPerHi
/**
* Renders all points from the given highres-model onto the lowres-grid
*/
public void render(HiresModel hiresModel) throws IOException {
public void render(HiresModel hiresModel) {
Vector3i min = hiresModel.getBlockMin();
Vector3i max = hiresModel.getBlockMax();
Vector3i size = max.sub(min).add(Vector3i.ONE);
@ -140,7 +140,7 @@ public synchronized void save(){
/**
* Updates a point on the lowresmodel-grid
*/
public void update(UUID world, Vector2i point, float height, Vector3f color) throws IOException {
public void update(UUID world, Vector2i point, float height, Vector3f color) {
Vector2i tile = pointToTile(point);
Vector2i relPoint = getPointRelativeToTile(tile, point);
LowresModel model = getModel(world, tile);
@ -175,7 +175,7 @@ public File getFile(Vector2i tile, boolean useGzip){
return FileUtils.coordsToFile(fileRoot, tile, "json" + (useGzip ? ".gz" : ""));
}
private LowresModel getModel(UUID world, Vector2i tile) throws IOException {
private LowresModel getModel(UUID world, Vector2i tile) {
File modelFile = getFile(tile, useGzip);
CachedModel model = models.get(modelFile);
@ -184,24 +184,19 @@ private LowresModel getModel(UUID world, Vector2i tile) throws IOException {
synchronized (this) {
model = models.get(modelFile);
if (model == null){
if (modelFile.exists()){
InputStream is = new FileInputStream(modelFile);
if (useGzip) is = new GZIPInputStream(is);
try {
try (FileInputStream fis = new FileInputStream(modelFile)) {
InputStream is = fis;
if (useGzip) is = new GZIPInputStream(is);
String json = IOUtils.toString(is, StandardCharsets.UTF_8);
try {
model = new CachedModel(world, tile, BufferGeometry.fromJson(json));
} catch (IllegalArgumentException | IOException ex){
Logger.global.logError("Failed to load lowres model: " + modelFile, ex);
//gridFile.renameTo(gridFile.toPath().getParent().resolve(gridFile.getName() + ".broken").toFile());
modelFile.delete();
}
} finally {
is.close();
model = new CachedModel(world, tile, BufferGeometry.fromJson(json));
} catch (IllegalArgumentException | IOException ex){
Logger.global.logError("Failed to load lowres model: " + modelFile, ex);
modelFile.delete();
}
}
if (model == null){

View File

@ -30,9 +30,11 @@
import java.util.stream.Collectors;
import com.flowpowered.math.vector.Vector2i;
import com.flowpowered.math.vector.Vector3f;
import de.bluecolored.bluemap.core.config.MainConfig.MapConfig;
import de.bluecolored.bluemap.core.render.TileRenderer;
import de.bluecolored.bluemap.core.util.MathUtils;
import de.bluecolored.bluemap.core.world.World;
import ninja.leaping.configurate.ConfigurationNode;
import ninja.leaping.configurate.gson.GsonConfigurationLoader;
@ -94,17 +96,17 @@ public double getDouble(Object... path) {
}
public Collection<String> getMapIds() {
return rootNode.getChildrenMap().keySet().stream().map(o -> o.toString()).collect(Collectors.toSet());
return rootNode.getNode("maps").getChildrenMap().keySet().stream().map(o -> o.toString()).collect(Collectors.toSet());
}
public void setAllEnabled(boolean enabled) {
for (ConfigurationNode mapNode : rootNode.getChildrenMap().values()) {
public void setAllMapsEnabled(boolean enabled) {
for (ConfigurationNode mapNode : rootNode.getNode("maps").getChildrenMap().values()) {
mapNode.getNode("enabled").setValue(enabled);
}
}
public void setEnabled(boolean enabled, String mapId) {
set(enabled, mapId, "enabled");
public void setMapEnabled(boolean enabled, String mapId) {
set(enabled, "maps", mapId, "enabled");
}
public void setFrom(TileRenderer tileRenderer, String mapId) {
@ -113,56 +115,60 @@ public void setFrom(TileRenderer tileRenderer, String mapId) {
Vector2i lowresTileSize = tileRenderer.getLowresModelManager().getTileSize();
Vector2i lowresPointsPerHiresTile = tileRenderer.getLowresModelManager().getPointsPerHiresTile();
set(hiresTileSize.getX(), mapId, "hires", "tileSize", "x");
set(hiresTileSize.getY(), mapId, "hires", "tileSize", "z");
set(1, mapId, "hires", "scale", "x");
set(1, mapId, "hires", "scale", "z");
set(gridOrigin.getX(), mapId, "hires", "translate", "x");
set(gridOrigin.getY(), mapId, "hires", "translate", "z");
set(hiresTileSize.getX(), "maps", mapId, "hires", "tileSize", "x");
set(hiresTileSize.getY(), "maps", mapId, "hires", "tileSize", "z");
set(1, "maps", mapId, "hires", "scale", "x");
set(1, "maps", mapId, "hires", "scale", "z");
set(gridOrigin.getX(), "maps", mapId, "hires", "translate", "x");
set(gridOrigin.getY(), "maps", mapId, "hires", "translate", "z");
Vector2i pointSize = hiresTileSize.div(lowresPointsPerHiresTile);
Vector2i tileSize = pointSize.mul(lowresTileSize);
set(tileSize.getX(), mapId, "lowres", "tileSize", "x");
set(tileSize.getY(), mapId, "lowres", "tileSize", "z");
set(pointSize.getX(), mapId, "lowres", "scale", "x");
set(pointSize.getY(), mapId, "lowres", "scale", "z");
set(pointSize.getX() / 2, mapId, "lowres", "translate", "x");
set(pointSize.getY() / 2, mapId, "lowres", "translate", "z");
set(tileSize.getX(), "maps", mapId, "lowres", "tileSize", "x");
set(tileSize.getY(), "maps", mapId, "lowres", "tileSize", "z");
set(pointSize.getX(), "maps", mapId, "lowres", "scale", "x");
set(pointSize.getY(), "maps", mapId, "lowres", "scale", "z");
set(pointSize.getX() / 2, "maps", mapId, "lowres", "translate", "x");
set(pointSize.getY() / 2, "maps", mapId, "lowres", "translate", "z");
}
public void setFrom(World world, String mapId) {
set(world.getSpawnPoint().getX(), mapId, "startPos", "x");
set(world.getSpawnPoint().getZ(), mapId, "startPos", "z");
set(world.getSpawnPoint().getX(), "maps", mapId, "startPos", "x");
set(world.getSpawnPoint().getZ(), "maps", mapId, "startPos", "z");
}
public void setFrom(MapConfig mapConfig, String mapId) {
Vector2i startPos = mapConfig.getStartPos();
if (startPos != null) {
set(startPos.getX(), mapId, "startPos", "x");
set(startPos.getY(), mapId, "startPos", "z");
set(startPos.getX(), "maps", mapId, "startPos", "x");
set(startPos.getY(), "maps", mapId, "startPos", "z");
}
set(mapConfig.getLowresViewDistance(), mapId, "lowres", "viewDistance");
set(mapConfig.getHiresViewDistance(), mapId, "hires", "viewDistance");
Vector3f skyColor = MathUtils.color3FromInt(mapConfig.getSkyColor());
set(skyColor.getX(), "maps", mapId, "skyColor", "r");
set(skyColor.getY(), "maps", mapId, "skyColor", "g");
set(skyColor.getZ(), "maps", mapId, "skyColor", "b");
set(mapConfig.getAmbientLight(), "maps", mapId, "ambientLight");
setName(mapConfig.getName(), mapId);
}
public void setOrdinal(int ordinal, String mapId) {
set(ordinal, mapId, "ordinal");
set(ordinal, "maps", mapId, "ordinal");
}
public int getOrdinal(String mapId) {
return getInt(mapId, "ordinal");
return getInt("maps", mapId, "ordinal");
}
public void setName(String name, String mapId) {
set(name, mapId, "name");
set(name, "maps", mapId, "name");
}
public String getName(String mapId) {
return getString(mapId, "name");
return getString("maps", mapId, "name");
}
}

View File

@ -0,0 +1,5 @@
{
"variants": {
"": { "model": "block/bubble_column" }
}
}

View File

@ -39,6 +39,7 @@ import {
Texture,
VertexColors,
WebGLRenderer,
Vector3,
} from 'three';
import UI from './ui/UI.js';
@ -54,6 +55,7 @@ import SKY_VERTEX_SHADER from './shaders/SkyVertexShader.js';
import SKY_FRAGMENT_SHADER from './shaders/SkyFragmentShader.js';
import { stringToImage, pathFromCoords } from './utils.js';
import {getCookie, setCookie} from "./utils";
export default class BlueMap {
constructor(element, dataRoot) {
@ -69,6 +71,12 @@ export default class BlueMap {
this.mobSpawnOverlay = {
value: false
};
this.ambientLight = {
value: 0
};
this.skyColor = {
value: new Vector3(0, 0, 0)
};
this.ui = new UI(this);
@ -88,6 +96,9 @@ export default class BlueMap {
await this.loadHiresMaterial();
await this.loadLowresMaterial();
this.loadUserSettings();
this.handleContainerResize();
this.changeMap(this.maps[0]);
this.ui.load();
@ -106,11 +117,18 @@ export default class BlueMap {
this.map = map;
let startPos = {
x: this.settings[this.map]["startPos"]["x"],
z: this.settings[this.map]["startPos"]["z"]
x: this.settings.maps[this.map]["startPos"]["x"],
z: this.settings.maps[this.map]["startPos"]["z"]
};
this.controls.setTileSize(this.settings[this.map]['hires']['tileSize']);
this.ambientLight.value = this.settings.maps[this.map]["ambientLight"];
this.skyColor.value.set(
this.settings.maps[this.map]["skyColor"].r,
this.settings.maps[this.map]["skyColor"].g,
this.settings.maps[this.map]["skyColor"].b
);
this.controls.setTileSize(this.settings.maps[this.map]['hires']['tileSize']);
this.controls.resetPosition();
this.controls.targetPosition.set(startPos.x, this.controls.targetPosition.y, startPos.z);
this.controls.position.copy(this.controls.targetPosition);
@ -120,7 +138,7 @@ export default class BlueMap {
this.lowresViewDistance,
this.loadLowresTile,
this.lowresScene,
this.settings[this.map]['lowres']['tileSize'],
this.settings.maps[this.map]['lowres']['tileSize'],
startPos
);
@ -129,7 +147,7 @@ export default class BlueMap {
this.hiresViewDistance,
this.loadHiresTile,
this.hiresScene,
this.settings[this.map]['hires']['tileSize'],
this.settings.maps[this.map]['hires']['tileSize'],
startPos
);
@ -197,6 +215,8 @@ export default class BlueMap {
update = () => {
setTimeout(this.update, 1000);
this.saveUserSettings();
this.lowresTileManager.setPosition(this.controls.targetPosition);
if (this.camera.position.y < 400) {
this.hiresTileManager.setPosition(this.controls.targetPosition);
@ -273,14 +293,14 @@ export default class BlueMap {
this.fileLoader.load(this.dataRoot + 'settings.json', settings => {
this.settings = JSON.parse(settings);
this.maps = [];
for (let map in this.settings) {
if (this.settings.hasOwnProperty(map) && this.settings[map].enabled){
for (let map in this.settings.maps) {
if (this.settings["maps"].hasOwnProperty(map) && this.settings.maps[map].enabled){
this.maps.push(map);
}
}
this.maps.sort((map1, map2) => {
var sort = this.settings[map1].ordinal - this.settings[map2].ordinal;
var sort = this.settings.maps[map1].ordinal - this.settings.maps[map2].ordinal;
if (isNaN(sort)) return 0;
return sort;
});
@ -321,11 +341,49 @@ export default class BlueMap {
$(window).resize(this.handleContainerResize);
}
loadUserSettings(){
if (!this.settings["useCookies"]) return;
this.mobSpawnOverlay.value = this.loadUserSetting("mobSpawnOverlay", this.mobSpawnOverlay.value);
this.targetSunLightStrength = this.loadUserSetting("sunLightStrength", this.targetSunLightStrength);
this.quality = this.loadUserSetting("renderQuality", this.quality);
this.hiresViewDistance = this.loadUserSetting("hiresViewDistance", this.hiresViewDistance);
this.lowresViewDistance = this.loadUserSetting("lowresViewDistance", this.lowresViewDistance);
}
saveUserSettings(){
if (!this.settings["useCookies"]) return;
if (this.savedUserSettings === undefined) this.savedUserSettings = {};
this.saveUserSetting("mobSpawnOverlay", this.mobSpawnOverlay.value);
this.saveUserSetting("sunLightStrength", this.targetSunLightStrength);
this.saveUserSetting("renderQuality", this.quality);
this.saveUserSetting("hiresViewDistance", this.hiresViewDistance);
this.saveUserSetting("lowresViewDistance", this.lowresViewDistance);
}
loadUserSetting(key, defaultValue){
let value = getCookie("bluemap-" + key);
if (value === undefined) return defaultValue;
return value;
}
saveUserSetting(key, value){
if (this.savedUserSettings[key] !== value){
this.savedUserSettings[key] = value;
setCookie("bluemap-" + key, value);
}
}
createSkybox() {
let geometry = new SphereGeometry(10, 10, 10);
let material = new ShaderMaterial({
uniforms: {
sunlightStrength: this.sunLightStrength
sunlightStrength: this.sunLightStrength,
ambientLight: this.ambientLight,
skyColor: this.skyColor,
},
vertexShader: SKY_VERTEX_SHADER,
fragmentShader: SKY_FRAGMENT_SHADER,
@ -364,7 +422,8 @@ export default class BlueMap {
value: texture
},
sunlightStrength: this.sunLightStrength,
mobSpawnOverlay: this.mobSpawnOverlay
mobSpawnOverlay: this.mobSpawnOverlay,
ambientLight: this.ambientLight,
};
let material = new ShaderMaterial({
@ -392,7 +451,8 @@ export default class BlueMap {
async loadLowresMaterial() {
this.lowresMaterial = new ShaderMaterial({
uniforms: {
sunlightStrength: this.sunLightStrength
sunlightStrength: this.sunLightStrength,
ambientLight: this.ambientLight,
},
vertexShader: LOWRES_VERTEX_SHADER,
fragmentShader: LOWRES_FRAGMENT_SHADER,
@ -414,9 +474,9 @@ export default class BlueMap {
this.bufferGeometryLoader.load(path, geometry => {
let object = new Mesh(geometry, this.hiresMaterial);
let tileSize = this.settings[this.map]['hires']['tileSize'];
let translate = this.settings[this.map]['hires']['translate'];
let scale = this.settings[this.map]['hires']['scale'];
let tileSize = this.settings.maps[this.map]['hires']['tileSize'];
let translate = this.settings.maps[this.map]['hires']['translate'];
let scale = this.settings.maps[this.map]['hires']['scale'];
object.position.set(tileX * tileSize.x + translate.x, 0, tileZ * tileSize.z + translate.z);
object.scale.set(scale.x, 1, scale.z);
@ -435,9 +495,9 @@ export default class BlueMap {
this.bufferGeometryLoader.load(path, geometry => {
let object = new Mesh(geometry, this.lowresMaterial);
let tileSize = this.settings[this.map]['lowres']['tileSize'];
let translate = this.settings[this.map]['lowres']['translate'];
let scale = this.settings[this.map]['lowres']['scale'];
let tileSize = this.settings.maps[this.map]['lowres']['tileSize'];
let translate = this.settings.maps[this.map]['lowres']['translate'];
let scale = this.settings.maps[this.map]['lowres']['scale'];
object.position.set(tileX * tileSize.x + translate.x, 0, tileZ * tileSize.z + translate.z);
object.scale.set(scale.x, 1, scale.z);
@ -458,8 +518,6 @@ export default class BlueMap {
`);
};
// ###### UI ######
toggleAlert(id, content) {
let alertBox = $(this.element).find('.alert-box');
if (alertBox.length === 0){
@ -497,4 +555,5 @@ export default class BlueMap {
displayAlert();
}
}

View File

@ -34,9 +34,8 @@ export default class MapSelection extends Dropdown {
this.bluemap = bluemap;
//add maps
const maps = this.bluemap.settings;
for (let mapId in maps) {
if (!maps.hasOwnProperty(mapId)) continue;
const maps = this.bluemap.settings.maps;
for (let mapId of this.bluemap.maps) {
const map = maps[mapId];
if (!map.enabled) continue;

View File

@ -26,6 +26,7 @@
const HIRES_FRAGMENT_SHADER = `
uniform sampler2D texture;
uniform float sunlightStrength;
uniform float ambientLight;
uniform bool mobSpawnOverlay;
varying vec3 vPosition;
@ -71,7 +72,7 @@ void main() {
//apply light
float light = max(vSunlight * sunlightStrength, vBlocklight);
color.rgb *= light / 15.0;
color.rgb *= max(light / 15.0, ambientLight);
gl_FragColor = color;
}

View File

@ -25,6 +25,7 @@
const LOWRES_FRAGMENT_SHADER = `
uniform float sunlightStrength;
uniform float ambientLight;
varying vec3 vPosition;
varying vec3 vNormal;
@ -37,7 +38,7 @@ void main() {
float diff = sqrt(max(dot(vNormal, vec3(0.3637, 0.7274, 0.5819)), 0.0)) * 0.4 + 0.6;
color *= diff;
color *= sunlightStrength;
color *= max(sunlightStrength, ambientLight);
gl_FragColor = color;
}

View File

@ -25,14 +25,13 @@
const SKY_FRAGMENT_SHADER = `
uniform float sunlightStrength;
uniform float ambientLight;
uniform vec3 skyColor;
varying vec3 vPosition;
void main() {
vec4 dayColor = vec4(0.49, 0.67, 1.0, 1.0);
vec4 nightColor = vec4(0.0, 0.02, 0.05, 1.0);
vec4 color = dayColor * sunlightStrength + nightColor * (1.0 - sunlightStrength);
vec4 color = vec4(skyColor * max(sunlightStrength, ambientLight), 1.0);
color.rgb *= (clamp(vPosition.y, -0.02, 0.02) + 0.02) * 25.0;
gl_FragColor = color;

View File

@ -118,7 +118,7 @@ export default class Dropdown extends Element {
this.select(value);
//close
option.parents(".select").slideUp(200);
this.closeAll();
if (event !== undefined) event.stopPropagation();

View File

@ -74,9 +74,9 @@ export default class UI {
this.blueMap.quality = parseFloat(value);
this.blueMap.handleContainerResize();
});
quality.addOption("2", "high");
quality.addOption("1", "normal", true);
quality.addOption("0.5", "low");
quality.addOption("2", "high", this.blueMap.quality === 2);
quality.addOption("1", "normal", this.blueMap.quality === 1);
quality.addOption("0.5", "low", this.blueMap.quality === 0.5);
let hiresSlider = new Slider(32, 480, 1, this.blueMap.hiresViewDistance, v => {
this.blueMap.hiresViewDistance = v.getValue();
this.blueMap.hiresTileManager.setViewDistance(this.blueMap.hiresViewDistance);

View File

@ -62,5 +62,44 @@ export const splitNumberToPath = num => {
export const hashTile = (x, z) => `x${x}z${z}`;
/**
* Adapted from https://www.w3schools.com/js/js_cookies.asp
*/
export const setCookie = (key, value, days = 360) => {
value = JSON.stringify(value);
let expireDate = new Date();
expireDate.setTime(expireDate.getTime() + days * 24 * 60 * 60 * 1000);
document.cookie = key + "=" + value + ";" + "expires=" + expireDate.toUTCString();
};
/**
* Adapted from https://www.w3schools.com/js/js_cookies.asp
*/
export const getCookie = key => {
let cookieString = decodeURIComponent(document.cookie);
let cookies = cookieString.split(';');
for(let i = 0; i < cookies.length; i++) {
let cookie = cookies[i];
while (cookie.charAt(0) === ' ') {
cookie = cookie.substring(1);
}
if (cookie.indexOf(key + "=") === 0) {
let value = cookie.substring(key.length + 1, cookie.length);
try {
value = JSON.parse(value);
} catch (e) {}
return value;
}
}
return undefined;
};
export const Vector2_ZERO = new Vector2(0, 0);
export const Vector3_ZERO = new Vector3(0, 0, 0);

View File

@ -2,11 +2,15 @@
$normal_fg: #333;
$normal_bg: #fff;
$super_light_fg: #484848;
$super_light_bg: #ddd;
$label_fg: #666;
$light_fg: #666;
$light_bg: #aaa;
$hover_fg: $normal_fg;
$hover_bg: #aaa;
$active_fg: $normal_bg;
$active_bg: $normal_fg;
$line_color: #aaa;
// breakpoints
$super-small-max: 500px;

View File

@ -33,7 +33,7 @@
&[data-axis]::before {
padding: 0 0.2rem 0 0.5rem;
line-height: 2rem;
color: $light_fg;
color: $label_fg;
content: attr(data-axis)':';
}
}

View File

@ -1,5 +1,17 @@
@import "constants";
@import "ui/ui";
@import "ui/element";
@import "ui/toolbar";
@import "ui/menu";
@import "ui/button";
@import "ui/slider";
@import "ui/togglebutton";
@import "ui/separator";
@import "ui/dropdown";
@import "ui/label";
@import "modules/position";
html, body {
margin: 0;
padding: 0;
@ -53,9 +65,6 @@ html, body {
width: 100%;
height: 100%;
color: $normal_fg;
filter: drop-shadow(1px 1px 3px #0008);
pointer-events: none;
z-index: 100;
@ -68,11 +77,10 @@ html, body {
position: relative;
flex-shrink: 0;
z-index: 200;
filter: drop-shadow(1px 1px 3px #0008);
z-index: 200;
@media (max-width: $middle-max) {
position: absolute;
}
@ -85,21 +93,11 @@ html, body {
pointer-events: none;
filter: drop-shadow(1px 1px 3px #0008);
> * {
pointer-events: auto;
}
}
}
}
@import "ui/ui";
@import "ui/element";
@import "ui/toolbar";
@import "ui/menu";
@import "ui/button";
@import "ui/slider";
@import "ui/togglebutton";
@import "ui/separator";
@import "ui/dropdown";
@import "ui/label";
@import "modules/position";

View File

@ -15,18 +15,19 @@
}
&:hover {
background-color: $element_fg;
color: $element_bg;
background-color: $hover_bg;
color: $hover_fg;
}
&:active {
background-color: $active_bg;
color: $active_fg;
> img {
filter: invert(1);
}
}
&:active {
background-color: $light_fg;
}
> img {
position: absolute;
top: 0;

View File

@ -11,7 +11,12 @@
padding-right: 1rem;
&:hover {
background-color: $light_bg;
background-color: $hover_bg;
color: $hover_fg;
&::after {
border-color: $hover_fg transparent transparent transparent;
}
}
> .ui-element {
@ -35,36 +40,41 @@
}
}
&.open > .header::after {
top: calc(50% - 0.6rem);
border-color: transparent transparent $normal_fg transparent;
&.open > .header {
background-color: $hover_bg;
color: $hover_fg;
&::after {
top: calc(50% - 0.6rem);
border-color: transparent transparent $hover_fg transparent;
}
}
> .select {
position: absolute;
top: calc(100% - 1px);
top: 100%;
left: 0;
width: calc(100% - 2px);
width: 100%;
overflow-x: hidden;
max-height: 300px;
overflow-y: auto;
border: solid 1px $light_bg;
z-index: 110;
> .option {
background-color: $super-light_bg;
&.selected {
background-color: $light_bg;
}
background-color: $normal_bg;
color: $normal_fg;
&:hover {
background-color: $normal_fg;
color: $normal_bg;
background-color: $hover_bg;
color: $hover_fg;
}
&.selected {
background-color: $active_bg;
color: $active_fg;
}
}
}

View File

@ -1,12 +1,6 @@
$element_fg: $normal_fg;
$element_bg: $normal_bg;
.bluemap-container .ui .ui-element {
position: relative;
background-color: $element_bg;
color: $element_fg;
min-width: 2rem;
min-height: 2rem;
line-height: 2rem;

View File

@ -1,5 +1,5 @@
.bluemap-container .ui .ui-element.label {
color: $light_fg;
color: $label_fg;
}

View File

@ -1,6 +1,6 @@
$menu-width: 375px;
.bluemap-container .menu {
.bluemap-container .ui .menu {
position: relative;
height: 100%;
@ -8,6 +8,7 @@ $menu-width: 375px;
max-width: 100%;
background-color: $normal_bg;
color: $normal_fg;
overflow: hidden;
@ -33,8 +34,8 @@ $menu-width: 375px;
top: 0;
width: $menu-width;
height: 1.5rem;
line-height: 1.5rem;
height: 2.5rem;
line-height: 2.5rem;
margin: 0;
padding: 0.25rem;
@ -62,21 +63,26 @@ $menu-width: 375px;
> .content {
position: absolute;
right: 0;
top: 2rem;
top: 3rem;
width: $menu-width;
width: calc(375px - 1rem);
height: calc(100% - 3rem);
padding-top: 0.5rem;
padding: 0.5rem;
overflow-y: auto;
@media (max-width: $menu-width) {
width: 100%;
width: calc(100% - 1rem);
}
> .separator {
border-top: solid 1px $light_bg;
position: relative;
left: -0.5rem;
width: calc(100% + 1rem);
border-top: solid 1px $line_color;
margin: 0.5rem 0;
}
@ -87,10 +93,17 @@ $menu-width: 375px;
line-height: 0.8rem;
}
> .dropdown > .select {
border: solid 1px $line_color;
border-top: none;
width: calc(100% - 2px);
}
// a little hacky to force not displaying any icon
> .toggle-button.icon {
> .label {
display: inline !important;
display: inline;
}
> img {
@ -98,16 +111,16 @@ $menu-width: 375px;
}
> .switch {
display: block !important;
display: block;
}
&.selected:not(:hover) {
background-color: $normal_bg !important;
color: $normal_fg !important;
background-color: $normal_bg;
color: $normal_fg;
}
&:hover {
background-color: $light_bg !important;
color: $normal_fg !important;
background-color: $hover_bg;
color: $hover_fg;
}
}
}

View File

@ -6,5 +6,4 @@
padding: 0;
background-color: unset;
color: $element_fg;
}

View File

@ -4,22 +4,19 @@
padding-right: 2.75rem;
}
&:hover,
&:active {
background-color: $light_bg;
color: $normal_fg;
background-color: $hover_bg;
color: $hover_fg;
> img {
filter: invert(0);
}
}
&.icon {
&:hover,
&:active {
background-color: $light_fg;
color: $normal_bg;
}
&.selected {
background-color: $normal_fg;
color: $normal_bg;
background-color: $active_bg;
color: $active_fg;
> img {
filter: invert(1);
@ -39,7 +36,7 @@
border-radius: 1rem;
background-color: $light_fg;
background-color: $normal_fg;
transition: background-color 0.2s;
@ -57,7 +54,7 @@
border-radius: 100%;
background-color: $light_bg;
background-color: $normal_bg;
transition: left 0.2s;
}

View File

@ -12,7 +12,7 @@
width: 100%;
margin: 0;
background-color: $super_light_bg;
background-color: $normal_bg;
> .mobile-hide {
display: none;
@ -30,8 +30,11 @@
> .ui-element {
flex-shrink: 0;
background-color: $normal_bg;
color: $normal_fg;
@media (max-width: $small-max) {
border-top: solid 1px $light_bg;
border-top: solid 1px $line_color;
margin-top: -1px;
}
@ -41,7 +44,7 @@
}
> .ui-element:not(.separator) + .ui-element:not(.separator) {
border-left: solid 1px $light_bg;
border-left: solid 1px $line_color;
margin-left: -1px;
}
@ -51,7 +54,7 @@
@media (max-width: $small-max) {
width: 0;
border-left: solid 1px $light_bg;
border-left: solid 1px $line_color;
margin-left: -1px;
}
@ -64,7 +67,7 @@
flex-grow: 1;
@media (max-width: $small-max) {
border-right: solid 1px $light_bg;
border-right: solid 1px $line_color;
margin-right: -1px;
z-index: 101;

View File

@ -49,7 +49,7 @@
width: 0.8rem;
height: 0.2rem;
background-color: $light_fg;
background-color: $normal_fg;
}
&::before {
@ -83,12 +83,13 @@
.alert {
position: relative;
pointer-events: all;
padding: 1rem;
margin: 1rem;
background-color: $normal_bg;
padding: 1rem;
color: $normal_fg;
margin: 1rem;
pointer-events: all;
}
}

View File

@ -3,6 +3,7 @@ metrics: false
renderThreadCount: -2
data: "bluemap"
webroot: "bluemap/web"
useCookies: true
webserver {
enabled: true
port: 8100

View File

@ -32,6 +32,9 @@ webroot: "bluemap/web"
# Default is "<webroot>/data"
#webdata: "path/to/data/folder"
# If the web-application should use cookies to save the configurations of a user.
useCookies: true
webserver {
# With this setting you can disable the integrated web-server.
# This is usefull if you want to only render the map-data for later use, or if you setup your own webserver.
@ -60,40 +63,43 @@ maps: [
{
# The id of this map
# Should only contain word-charactes: [a-zA-Z0-9_]
# Changing this value breaks your existing renders.
id: "world"
# The name of this map
# This defines the display name of this map, you can change this at any time
# This defines the display name of this map, you can change this at any time.
# Default is the id of this map
name: "World"
# The path to the save-folder of the world to render
# The path to the save-folder of the world to render.
world: "world"
# The position on the world where the map will be centered if you open it.
# You can change this at any time.
# This defaults to the world-spawn if you don't set it.
#startPos: [500, -820]
# The color of thy sky as a hex-color
# You can change this at any time.
# Default is "#7dabff"
skyColor: "#7dabff"
# Defines the ambient light-strength that every block is recieving, regardless of the sunlight/blocklight.
# 0 is no ambient light, 1 is fully lighted.
# You can change this at any time.
# Default is 0
ambientLight: 0
# If this is false, BlueMap tries to omit all blocks that are not visible from above-ground.
# More specific: Block-Faces that have a sunlight/skylight value of 0 are removed.
# This improves the performance of the map on slower devices by a lot, but might cause some blocks to disappear that should normally be visible.
# Changing this value requires a re-render of the map.
# Default is false
renderCaves: false
# AmbientOcclusion adds soft shadows into corners, which gives the map a much better look.
# This has only a small impact on render-time and has no impact on the web-performance of the map.
# The value defines the strength of the shading, a value of 0 disables ambientOcclusion.
# Default is 0.25
ambientOcclusion: 0.25
# Lighting uses the light-data in minecraft to shade each block-face.
# If this is enabled, caves and inside buildings without torches will be darker.
# The value defines the strength of the shading and a value of 0 disables lighting (every block will be fully lit).
# Default is 0.8
lighting: 0.8
# With the below values you can limit the map-render.
# This can be used to ignore the nethers ceiling or render only a certain part of a world.
# Changing this values might require a re-render of the map, already rendered tiles outside the limits will not be deleted.
# Default is no min or max value (= infinite bounds)
#minX: -4000
#maxX: 4000
@ -105,43 +111,17 @@ maps: [
# Using this, BlueMap pretends that every Block out of the defined render-bounds is AIR,
# this means you can see the blocks where the world is cut (instead of having a see-through/xray view).
# This has only an effect if you set some render-bounds above.
# Default is enabled
# Changing this value requires a re-render of the map.
# Default is true
renderEdges: true
# With this set to true, the generated files for this world are compressed using gzip to save A LOT of space.
# Files will be only 5% as big with compression!
# Note: If you are using NGINX or Apache to host your map, you can configure them to serve the compressed files directly.
# This is much better than disabling the compression.
# Changing this value requires a re-render of the map.
# Default is true
useCompression: true
# HIRES is the high-resolution render of the map. Where you see every block.
hires {
# Defines the size of one map-tile in blocks.
# If you change this value, the lowres values might need adjustment as well!
# Default is 32
tileSize: 32
# The View-Distance for hires tiles on the web-map (the value is the radius in tiles)
# Default is 4.5
viewDistance: 4.5
}
# LOWRES is the low-resolution render of the map. Thats the model that you see if you zoom far out to get an overview.
lowres {
# Defines resolution of the lowres model. E.g. If the hires.tileSize is 32, a value of 4 means that every 8*8 blocks will be summarized by one point on the lowres map.
# Calculation: 32 / 4 = 8
# You can only use values that result in an integer if you use the above calculation!
# Default is 4
pointsPerHiresTile: 4
# Defines the size of one lowres-map-tile in points.
# Default is 50
pointsPerLowresTile: 50
# The View-Distance for lowres tiles on the web-map (the value is the radius in tiles)
# Default is 7
viewDistance: 7
}
}
# Here another example for the End-Map
@ -154,8 +134,8 @@ maps: [
# In the end is no sky-light, so we need to enable this or we won't see anything.
renderCaves: true
# Same here, we don't want a dark map. But not completely disabled, so we see the effect of e.g torches.
lighting: 0.4
# Same here, we don't want a dark map. But not completely lighted, so we see the effect of e.g torches.
ambientLight: 0.6
}
# Here another example for the Nether-Map
@ -165,7 +145,7 @@ maps: [
world: "world/DIM-1"
renderCaves: true
lighting: 0.6
ambientLight: 0.6
# We slice the whole world at y:90 so every block above 90 will be air.
# This way we don't render the nethers ceiling.