mirror of
https://github.com/BlueMap-Minecraft/BlueMap.git
synced 2024-11-22 10:35:16 +01:00
Fix several lighting issues on high and lowres renders
This commit is contained in:
parent
31e35ce205
commit
eadf854c50
@ -32,11 +32,9 @@
|
|||||||
import de.bluecolored.bluemap.core.debug.DebugDump;
|
import de.bluecolored.bluemap.core.debug.DebugDump;
|
||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
import de.bluecolored.bluemap.core.map.BmMap;
|
import de.bluecolored.bluemap.core.map.BmMap;
|
||||||
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
|
|
||||||
import de.bluecolored.bluemap.core.mca.MCAWorld;
|
import de.bluecolored.bluemap.core.mca.MCAWorld;
|
||||||
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
|
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
|
||||||
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
|
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
|
||||||
import de.bluecolored.bluemap.core.world.SlicedWorld;
|
|
||||||
import de.bluecolored.bluemap.core.world.World;
|
import de.bluecolored.bluemap.core.world.World;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
|
|
||||||
@ -156,7 +154,7 @@ private synchronized void loadWorldsAndMaps() throws IOException, InterruptedExc
|
|||||||
World world = worlds.get(worldUUID);
|
World world = worlds.get(worldUUID);
|
||||||
if (world == null) {
|
if (world == null) {
|
||||||
try {
|
try {
|
||||||
world = MCAWorld.load(worldFolder.toPath(), worldUUID, worldNameProvider.apply(worldUUID), mapConfig.isIgnoreMissingLightData());
|
world = MCAWorld.load(worldFolder.toPath(), worldUUID, worldNameProvider.apply(worldUUID), 15, mapConfig.isIgnoreMissingLightData());
|
||||||
worlds.put(worldUUID, world);
|
worlds.put(worldUUID, world);
|
||||||
} catch (MissingResourcesException e) {
|
} catch (MissingResourcesException e) {
|
||||||
throw e; // rethrow this to stop loading and display resource-missing message
|
throw e; // rethrow this to stop loading and display resource-missing message
|
||||||
@ -165,19 +163,6 @@ private synchronized void loadWorldsAndMaps() throws IOException, InterruptedExc
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//slice world if configured
|
|
||||||
if (!mapConfig.getMin().equals(RenderSettings.DEFAULT_MIN) || !mapConfig.getMax().equals(RenderSettings.DEFAULT_MAX)) {
|
|
||||||
if (mapConfig.isRenderEdges()) {
|
|
||||||
world = new SlicedWorld(world, mapConfig.getMin(), mapConfig.getMax());
|
|
||||||
} else {
|
|
||||||
world = new SlicedWorld(
|
|
||||||
world,
|
|
||||||
mapConfig.getMin().min(mapConfig.getMin().sub(2, 2, 2)), // protect from int-overflow
|
|
||||||
mapConfig.getMax().max(mapConfig.getMax().add(2, 2, 2)) // protect from int-overflow
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BmMap map = new BmMap(
|
BmMap map = new BmMap(
|
||||||
id,
|
id,
|
||||||
|
@ -94,7 +94,7 @@ private static List<Vector2i> getRegions(World world) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static List<Vector2i> getRegions(World world, Vector2i center, int radius) {
|
private static List<Vector2i> getRegions(World world, Vector2i center, int radius) {
|
||||||
if (center == null || radius < 0) return new ArrayList<>(world.listRegions());
|
if (center == null || radius < 0) return new ArrayList<>(world.listRegions()); //TODO: remove regions outside render-boundaries
|
||||||
|
|
||||||
List<Vector2i> regions = new ArrayList<>();
|
List<Vector2i> regions = new ArrayList<>();
|
||||||
|
|
||||||
|
@ -115,7 +115,9 @@ public void doWork() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Logger.global.logInfo("Working on " + worldRegion + " - Tile " + tile);
|
//Logger.global.logInfo("Working on " + worldRegion + " - Tile " + tile);
|
||||||
map.renderTile(tile); // <- actual work
|
if (isAllChunksInTileGenerated(tile)) {
|
||||||
|
map.renderTile(tile); // <- actual work
|
||||||
|
}
|
||||||
|
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
this.atWork--;
|
this.atWork--;
|
||||||
@ -126,6 +128,22 @@ public void doWork() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isAllChunksInTileGenerated(Vector2i tile) {
|
||||||
|
Grid tileGrid = map.getHiresModelManager().getTileGrid();
|
||||||
|
Grid chunkGrid = map.getWorld().getChunkGrid();
|
||||||
|
|
||||||
|
Vector2i minChunk = tileGrid.getCellMin(tile, chunkGrid);
|
||||||
|
Vector2i maxChunk = tileGrid.getCellMax(tile, chunkGrid);
|
||||||
|
|
||||||
|
for (int x = minChunk.getX(); x <= maxChunk.getX(); x++) {
|
||||||
|
for (int z = minChunk.getY(); z <= maxChunk.getY(); z++) {
|
||||||
|
if (!map.getWorld().getChunk(x, z).isGenerated()) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void complete() {
|
private void complete() {
|
||||||
map.getRenderState().setRenderTime(worldRegion, startTime);
|
map.getRenderState().setRenderTime(worldRegion, startTime);
|
||||||
|
|
||||||
|
@ -45,6 +45,7 @@ public class MapConfig implements MapSettings {
|
|||||||
private Vector2i startPos;
|
private Vector2i startPos;
|
||||||
private int skyColor;
|
private int skyColor;
|
||||||
private float ambientLight;
|
private float ambientLight;
|
||||||
|
private int worldSkyLight;
|
||||||
|
|
||||||
private boolean renderCaves;
|
private boolean renderCaves;
|
||||||
|
|
||||||
@ -82,6 +83,9 @@ public MapConfig(ConfigurationNode node) throws IOException {
|
|||||||
|
|
||||||
//ambientLight
|
//ambientLight
|
||||||
this.ambientLight = node.node("ambientLight").getFloat(0f);
|
this.ambientLight = node.node("ambientLight").getFloat(0f);
|
||||||
|
|
||||||
|
//worldSkyLight
|
||||||
|
this.worldSkyLight = node.node("worldSkyLight").getInt(15);
|
||||||
|
|
||||||
//renderCaves
|
//renderCaves
|
||||||
this.renderCaves = node.node("renderCaves").getBoolean(false);
|
this.renderCaves = node.node("renderCaves").getBoolean(false);
|
||||||
@ -101,7 +105,7 @@ public MapConfig(ConfigurationNode node) throws IOException {
|
|||||||
|
|
||||||
//useCompression
|
//useCompression
|
||||||
this.useGzip = node.node("useCompression").getBoolean(true);
|
this.useGzip = node.node("useCompression").getBoolean(true);
|
||||||
|
|
||||||
//ignoreMissingLightData
|
//ignoreMissingLightData
|
||||||
this.ignoreMissingLightData = node.node("ignoreMissingLightData").getBoolean(false);
|
this.ignoreMissingLightData = node.node("ignoreMissingLightData").getBoolean(false);
|
||||||
|
|
||||||
@ -135,11 +139,17 @@ public Vector2i getStartPos() {
|
|||||||
public int getSkyColor() {
|
public int getSkyColor() {
|
||||||
return skyColor;
|
return skyColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public float getAmbientLight() {
|
public float getAmbientLight() {
|
||||||
return ambientLight;
|
return ambientLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getWorldSkyLight() {
|
||||||
|
return worldSkyLight;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRenderCaves() {
|
public boolean isRenderCaves() {
|
||||||
return renderCaves;
|
return renderCaves;
|
||||||
}
|
}
|
||||||
|
@ -1,126 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of BlueMap, licensed under the MIT License (MIT).
|
|
||||||
*
|
|
||||||
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
|
|
||||||
* Copyright (c) contributors
|
|
||||||
*
|
|
||||||
* 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 de.bluecolored.bluemap.core.debug;
|
|
||||||
|
|
||||||
import com.flowpowered.math.vector.Vector2i;
|
|
||||||
import com.flowpowered.math.vector.Vector3i;
|
|
||||||
import de.bluecolored.bluemap.core.world.Chunk;
|
|
||||||
import de.bluecolored.bluemap.core.world.Grid;
|
|
||||||
import de.bluecolored.bluemap.core.world.Region;
|
|
||||||
import de.bluecolored.bluemap.core.world.World;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class OneBlockWorld implements World {
|
|
||||||
|
|
||||||
private final World delegate;
|
|
||||||
|
|
||||||
public OneBlockWorld(World delegate) {
|
|
||||||
this.delegate = delegate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return delegate.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UUID getUUID() {
|
|
||||||
return delegate.getUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Path getSaveFolder() {
|
|
||||||
return delegate.getSaveFolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSeaLevel() {
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector3i getSpawnPoint() {
|
|
||||||
return new Vector3i(0, 70, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxY(int x, int z) {
|
|
||||||
return 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinY(int x, int z) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Grid getChunkGrid() {
|
|
||||||
return delegate.getChunkGrid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Grid getRegionGrid() {
|
|
||||||
return delegate.getRegionGrid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Chunk getChunkAtBlock(int x, int y, int z) {
|
|
||||||
return delegate.getChunkAtBlock(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Chunk getChunk(int x, int z) {
|
|
||||||
return delegate.getChunk(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Region getRegion(int x, int z) {
|
|
||||||
return delegate.getRegion(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Vector2i> listRegions() {
|
|
||||||
return delegate.listRegions();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateChunkCache() {
|
|
||||||
delegate.invalidateChunkCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateChunkCache(int x, int z) {
|
|
||||||
delegate.invalidateChunkCache(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanUpChunkCache() {
|
|
||||||
delegate.cleanUpChunkCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -55,7 +55,7 @@ public HiresTileMeta render(World world, Vector3i modelMin, Vector3i modelMax, H
|
|||||||
|
|
||||||
int maxHeight, minY, maxY;
|
int maxHeight, minY, maxY;
|
||||||
Color columnColor = new Color(), blockColor = new Color();
|
Color columnColor = new Color(), blockColor = new Color();
|
||||||
BlockNeighborhood<?> block = new BlockNeighborhood<>(resourcePack, world, 0, 0, 0);
|
BlockNeighborhood<?> block = new BlockNeighborhood<>(resourcePack, renderSettings, world, 0, 0, 0);
|
||||||
BlockModelView blockModel = new BlockModelView(model);
|
BlockModelView blockModel = new BlockModelView(model);
|
||||||
|
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
@ -65,35 +65,39 @@ public HiresTileMeta render(World world, Vector3i modelMin, Vector3i modelMax, H
|
|||||||
maxHeight = 0;
|
maxHeight = 0;
|
||||||
columnColor.set(0, 0, 0, 1, true);
|
columnColor.set(0, 0, 0, 1, true);
|
||||||
|
|
||||||
minY = Math.max(min.getY(), world.getMinY(x, z));
|
if (renderSettings.isInsideRenderBoundaries(x, z)) {
|
||||||
maxY = Math.min(max.getY(), world.getMaxY(x, z));
|
minY = Math.max(min.getY(), world.getMinY(x, z));
|
||||||
|
maxY = Math.min(max.getY(), world.getMaxY(x, z));
|
||||||
|
|
||||||
for (y = minY; y <= maxY; y++){
|
for (y = minY; y <= maxY; y++) {
|
||||||
block.set(x, y, z);
|
block.set(x, y, z);
|
||||||
blockColor.set(0, 0, 0, 0, true);
|
if (!block.isInsideRenderBounds()) continue;
|
||||||
blockModel.initialize();
|
|
||||||
|
blockColor.set(0, 0, 0, 0, true);
|
||||||
|
blockModel.initialize();
|
||||||
|
|
||||||
try {
|
|
||||||
modelFactory.render(block, blockModel, blockColor);
|
|
||||||
} catch (NoSuchResourceException e) {
|
|
||||||
try {
|
try {
|
||||||
modelFactory.render(block, BlockState.MISSING, blockModel.reset(), blockColor);
|
modelFactory.render(block, blockModel, blockColor);
|
||||||
} catch (NoSuchResourceException e2) {
|
} catch (NoSuchResourceException e) {
|
||||||
e.addSuppressed(e2);
|
try {
|
||||||
|
modelFactory.render(block, BlockState.MISSING, blockModel.reset(), blockColor);
|
||||||
|
} catch (NoSuchResourceException e2) {
|
||||||
|
e.addSuppressed(e2);
|
||||||
|
}
|
||||||
|
//Logger.global.noFloodDebug(block.getBlockState().getFullId() + "-hiresModelRenderer-blockmodelerr", "Failed to create BlockModel for BlockState: " + block.getBlockState() + " (" + e.toString() + ")");
|
||||||
}
|
}
|
||||||
//Logger.global.noFloodDebug(block.getBlockState().getFullId() + "-hiresModelRenderer-blockmodelerr", "Failed to create BlockModel for BlockState: " + block.getBlockState() + " (" + e.toString() + ")");
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip empty blocks
|
// skip empty blocks
|
||||||
if (blockModel.getSize() <= 0) continue;
|
if (blockModel.getSize() <= 0) continue;
|
||||||
|
|
||||||
// move block-model to correct position
|
// move block-model to correct position
|
||||||
blockModel.translate(x - modelAnchor.getX(), y - modelAnchor.getY(), z - modelAnchor.getZ());
|
blockModel.translate(x - modelAnchor.getX(), y - modelAnchor.getY(), z - modelAnchor.getZ());
|
||||||
|
|
||||||
//update color and height (only if not 100% translucent)
|
//update color and height (only if not 100% translucent)
|
||||||
if (blockColor.a > 0) {
|
if (blockColor.a > 0) {
|
||||||
maxHeight = y;
|
maxHeight = y;
|
||||||
columnColor.overlay(blockColor);
|
columnColor.overlay(blockColor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +52,9 @@ default Vector3i getMax() {
|
|||||||
return DEFAULT_MAX;
|
return DEFAULT_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getAmbientLight();
|
||||||
|
|
||||||
|
int getWorldSkyLight();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The same as the maximum height, but blocks that are above this value are treated as AIR.<br>
|
* The same as the maximum height, but blocks that are above this value are treated as AIR.<br>
|
||||||
@ -67,5 +70,29 @@ default boolean isRenderEdges() {
|
|||||||
default boolean useGzipCompression() {
|
default boolean useGzipCompression() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean isInsideRenderBoundaries(int x, int z) {
|
||||||
|
Vector3i min = getMin();
|
||||||
|
Vector3i max = getMax();
|
||||||
|
|
||||||
|
return
|
||||||
|
x >= min.getX() &&
|
||||||
|
x <= max.getX() &&
|
||||||
|
z >= min.getZ() &&
|
||||||
|
z <= max.getZ();
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isInsideRenderBoundaries(int x, int y, int z) {
|
||||||
|
Vector3i min = getMin();
|
||||||
|
Vector3i max = getMax();
|
||||||
|
|
||||||
|
return
|
||||||
|
x >= min.getX() &&
|
||||||
|
x <= max.getX() &&
|
||||||
|
z >= min.getZ() &&
|
||||||
|
z <= max.getZ() &&
|
||||||
|
y >= min.getY() &&
|
||||||
|
y <= max.getY();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@
|
|||||||
import de.bluecolored.bluemap.core.util.math.VectorM3f;
|
import de.bluecolored.bluemap.core.util.math.VectorM3f;
|
||||||
import de.bluecolored.bluemap.core.world.BlockNeighborhood;
|
import de.bluecolored.bluemap.core.world.BlockNeighborhood;
|
||||||
import de.bluecolored.bluemap.core.world.BlockState;
|
import de.bluecolored.bluemap.core.world.BlockState;
|
||||||
import de.bluecolored.bluemap.core.world.ResourcePackBlock;
|
import de.bluecolored.bluemap.core.world.ExtendedBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A model builder for all liquid blocks
|
* A model builder for all liquid blocks
|
||||||
@ -144,10 +144,11 @@ private void build() {
|
|||||||
blockColor.multiply(tintcolor);
|
blockColor.multiply(tintcolor);
|
||||||
|
|
||||||
// apply light
|
// apply light
|
||||||
float sl = block.getSunLightLevel() / 16f;
|
float combinedLight = Math.max(block.getSunLightLevel() / 15f, block.getBlockLightLevel() / 15f);
|
||||||
blockColor.r *= sl;
|
combinedLight = (renderSettings.getAmbientLight() + combinedLight) / (renderSettings.getAmbientLight() + 1f);
|
||||||
blockColor.g *= sl;
|
blockColor.r *= combinedLight;
|
||||||
blockColor.b *= sl;
|
blockColor.g *= combinedLight;
|
||||||
|
blockColor.b *= combinedLight;
|
||||||
} else {
|
} else {
|
||||||
blockColor.set(0, 0, 0, 0, true);
|
blockColor.set(0, 0, 0, 0, true);
|
||||||
}
|
}
|
||||||
@ -166,7 +167,7 @@ private float getLiquidCornerHeight(int x, int z){
|
|||||||
|
|
||||||
float sumHeight = 0f;
|
float sumHeight = 0f;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
ResourcePackBlock<?> neighbor;
|
ExtendedBlock<?> neighbor;
|
||||||
BlockState neighborBlockState;
|
BlockState neighborBlockState;
|
||||||
|
|
||||||
for (ix = x; ix <= x+1; ix++){
|
for (ix = x; ix <= x+1; ix++){
|
||||||
@ -197,7 +198,7 @@ private boolean isLiquidBlockingBlock(BlockState blockState){
|
|||||||
return !blockState.equals(BlockState.AIR);
|
return !blockState.equals(BlockState.AIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSameLiquid(ResourcePackBlock<?> block){
|
private boolean isSameLiquid(ExtendedBlock<?> block){
|
||||||
if (block.getBlockState().getFullId().equals(this.blockState.getFullId())) return true;
|
if (block.getBlockState().getFullId().equals(this.blockState.getFullId())) return true;
|
||||||
return this.blockState.isWater() && (block.getBlockState().isWaterlogged() || block.getProperties().isAlwaysWaterlogged());
|
return this.blockState.isWater() && (block.getBlockState().isWaterlogged() || block.getProperties().isAlwaysWaterlogged());
|
||||||
}
|
}
|
||||||
@ -217,7 +218,7 @@ private boolean createElementFace(Direction faceDir, VectorM3f c0, VectorM3f c1,
|
|||||||
Vector3i faceDirVector = faceDir.toVector();
|
Vector3i faceDirVector = faceDir.toVector();
|
||||||
|
|
||||||
//face culling
|
//face culling
|
||||||
ResourcePackBlock<?> bl = block.getNeighborBlock(
|
ExtendedBlock<?> bl = block.getNeighborBlock(
|
||||||
faceDirVector.getX(),
|
faceDirVector.getX(),
|
||||||
faceDirVector.getY(),
|
faceDirVector.getY(),
|
||||||
faceDirVector.getZ()
|
faceDirVector.getZ()
|
||||||
@ -341,7 +342,7 @@ private int getFlowingAngle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private float compareLiquidHeights(float ownHeight, int dx, int dz) {
|
private float compareLiquidHeights(float ownHeight, int dx, int dz) {
|
||||||
ResourcePackBlock<?> neighbor = block.getNeighborBlock(dx, 0, dz);
|
ExtendedBlock<?> neighbor = block.getNeighborBlock(dx, 0, dz);
|
||||||
if (neighbor.getBlockState().isAir()) return 0;
|
if (neighbor.getBlockState().isAir()) return 0;
|
||||||
if (!isSameLiquid(neighbor)) return 0;
|
if (!isSameLiquid(neighbor)) return 0;
|
||||||
|
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
import de.bluecolored.bluemap.core.util.math.VectorM3f;
|
import de.bluecolored.bluemap.core.util.math.VectorM3f;
|
||||||
import de.bluecolored.bluemap.core.world.BlockNeighborhood;
|
import de.bluecolored.bluemap.core.world.BlockNeighborhood;
|
||||||
import de.bluecolored.bluemap.core.world.LightData;
|
import de.bluecolored.bluemap.core.world.LightData;
|
||||||
import de.bluecolored.bluemap.core.world.ResourcePackBlock;
|
import de.bluecolored.bluemap.core.world.ExtendedBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This model builder creates a BlockStateModel using the information from parsed resource-pack json files.
|
* This model builder creates a BlockStateModel using the information from parsed resource-pack json files.
|
||||||
@ -160,12 +160,12 @@ private void createElementFace(BlockModelResource.Element element, Direction fac
|
|||||||
|
|
||||||
// face culling
|
// face culling
|
||||||
if (face.getCullface() != null) {
|
if (face.getCullface() != null) {
|
||||||
ResourcePackBlock<?> b = getRotationRelativeBlock(face.getCullface());
|
ExtendedBlock<?> b = getRotationRelativeBlock(face.getCullface());
|
||||||
if (b.getProperties().isCulling()) return;
|
if (b.getProperties().isCulling()) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// light calculation
|
// light calculation
|
||||||
ResourcePackBlock<?> facedBlockNeighbor = getRotationRelativeBlock(faceDir);
|
ExtendedBlock<?> facedBlockNeighbor = getRotationRelativeBlock(faceDir);
|
||||||
LightData blockLightData = block.getLightData();
|
LightData blockLightData = block.getLightData();
|
||||||
LightData facedLightData = facedBlockNeighbor.getLightData();
|
LightData facedLightData = facedBlockNeighbor.getLightData();
|
||||||
|
|
||||||
@ -307,20 +307,21 @@ private void createElementFace(BlockModelResource.Element element, Direction fac
|
|||||||
}
|
}
|
||||||
|
|
||||||
// apply light
|
// apply light
|
||||||
float sl = sunLight / 16f;
|
float combinedLight = Math.max(sunLight / 15f, blockLight / 15f);
|
||||||
mapColor.r *= sl;
|
combinedLight = (renderSettings.getAmbientLight() + combinedLight) / (renderSettings.getAmbientLight() + 1f);
|
||||||
mapColor.g *= sl;
|
mapColor.r *= combinedLight;
|
||||||
mapColor.b *= sl;
|
mapColor.g *= combinedLight;
|
||||||
|
mapColor.b *= combinedLight;
|
||||||
|
|
||||||
blockColor.add(mapColor);
|
blockColor.add(mapColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourcePackBlock<?> getRotationRelativeBlock(Direction direction){
|
private ExtendedBlock<?> getRotationRelativeBlock(Direction direction){
|
||||||
return getRotationRelativeBlock(direction.toVector());
|
return getRotationRelativeBlock(direction.toVector());
|
||||||
}
|
}
|
||||||
|
|
||||||
private ResourcePackBlock<?> getRotationRelativeBlock(Vector3i direction){
|
private ExtendedBlock<?> getRotationRelativeBlock(Vector3i direction){
|
||||||
return getRotationRelativeBlock(
|
return getRotationRelativeBlock(
|
||||||
direction.getX(),
|
direction.getX(),
|
||||||
direction.getY(),
|
direction.getY(),
|
||||||
@ -329,7 +330,7 @@ private ResourcePackBlock<?> getRotationRelativeBlock(Vector3i direction){
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final VectorM3f rotationRelativeBlockDirection = new VectorM3f(0, 0, 0);
|
private final VectorM3f rotationRelativeBlockDirection = new VectorM3f(0, 0, 0);
|
||||||
private ResourcePackBlock<?> getRotationRelativeBlock(int dx, int dy, int dz){
|
private ExtendedBlock<?> getRotationRelativeBlock(int dx, int dy, int dz){
|
||||||
rotationRelativeBlockDirection.set(dx, dy, dz);
|
rotationRelativeBlockDirection.set(dx, dy, dz);
|
||||||
makeRotationRelative(rotationRelativeBlockDirection);
|
makeRotationRelative(rotationRelativeBlockDirection);
|
||||||
|
|
||||||
|
@ -42,8 +42,8 @@ public class ChunkAnvil113 extends MCAChunk {
|
|||||||
private int[] biomes;
|
private int[] biomes;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ChunkAnvil113(CompoundTag chunkTag, boolean ignoreMissingLightData) {
|
public ChunkAnvil113(MCAWorld world, CompoundTag chunkTag) {
|
||||||
super(chunkTag);
|
super(world, chunkTag);
|
||||||
|
|
||||||
CompoundTag levelData = chunkTag.getCompoundTag("Level");
|
CompoundTag levelData = chunkTag.getCompoundTag("Level");
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ public ChunkAnvil113(CompoundTag chunkTag, boolean ignoreMissingLightData) {
|
|||||||
this.isGenerated = status.equals("full");
|
this.isGenerated = status.equals("full");
|
||||||
this.hasLight = isGenerated;
|
this.hasLight = isGenerated;
|
||||||
|
|
||||||
if (!isGenerated && ignoreMissingLightData) {
|
if (!isGenerated && getWorld().isIgnoreMissingLightData()) {
|
||||||
isGenerated = !status.equals("empty");
|
isGenerated = !status.equals("empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,14 +103,14 @@ public BlockState getBlockState(int x, int y, int z) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LightData getLightData(int x, int y, int z, LightData target) {
|
public LightData getLightData(int x, int y, int z, LightData target) {
|
||||||
if (!hasLight) return target.set(15, 0);
|
if (!hasLight) return target.set(getWorld().getSkyLight(), 0);
|
||||||
|
|
||||||
int sectionY = y >> 4;
|
int sectionY = y >> 4;
|
||||||
if (sectionY < 0 || sectionY >= this.sections.length)
|
if (sectionY < 0 || sectionY >= this.sections.length)
|
||||||
return (y < 0) ? target.set(0, 0) : target.set(15, 0);
|
return (y < 0) ? target.set(0, 0) : target.set(getWorld().getSkyLight(), 0);
|
||||||
|
|
||||||
Section section = this.sections[sectionY];
|
Section section = this.sections[sectionY];
|
||||||
if (section == null) return target.set(15, 0);
|
if (section == null) return target.set(getWorld().getSkyLight(), 0);
|
||||||
|
|
||||||
return section.getLightData(x, y, z, target);
|
return section.getLightData(x, y, z, target);
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,8 @@ public class ChunkAnvil115 extends MCAChunk {
|
|||||||
private int[] biomes;
|
private int[] biomes;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ChunkAnvil115(CompoundTag chunkTag, boolean ignoreMissingLightData) {
|
public ChunkAnvil115(MCAWorld world, CompoundTag chunkTag) {
|
||||||
super(chunkTag);
|
super(world, chunkTag);
|
||||||
|
|
||||||
CompoundTag levelData = chunkTag.getCompoundTag("Level");
|
CompoundTag levelData = chunkTag.getCompoundTag("Level");
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ public ChunkAnvil115(CompoundTag chunkTag, boolean ignoreMissingLightData) {
|
|||||||
this.isGenerated = status.equals("full");
|
this.isGenerated = status.equals("full");
|
||||||
this.hasLight = isGenerated;
|
this.hasLight = isGenerated;
|
||||||
|
|
||||||
if (!isGenerated && ignoreMissingLightData) {
|
if (!isGenerated && getWorld().isIgnoreMissingLightData()) {
|
||||||
isGenerated = !status.equals("empty");
|
isGenerated = !status.equals("empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,14 +103,14 @@ public BlockState getBlockState(int x, int y, int z) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LightData getLightData(int x, int y, int z, LightData target) {
|
public LightData getLightData(int x, int y, int z, LightData target) {
|
||||||
if (!hasLight) return target.set(15, 0);
|
if (!hasLight) return target.set(getWorld().getSkyLight(), 0);
|
||||||
|
|
||||||
int sectionY = y >> 4;
|
int sectionY = y >> 4;
|
||||||
if (sectionY < 0 || sectionY >= this.sections.length)
|
if (sectionY < 0 || sectionY >= this.sections.length)
|
||||||
return (y < 0) ? target.set(0, 0) : target.set(15, 0);
|
return (y < 0) ? target.set(0, 0) : target.set(getWorld().getSkyLight(), 0);
|
||||||
|
|
||||||
Section section = this.sections[sectionY];
|
Section section = this.sections[sectionY];
|
||||||
if (section == null) return target.set(15, 0);
|
if (section == null) return target.set(getWorld().getSkyLight(), 0);
|
||||||
|
|
||||||
return section.getLightData(x, y, z, target);
|
return section.getLightData(x, y, z, target);
|
||||||
}
|
}
|
||||||
|
@ -46,8 +46,8 @@ public class ChunkAnvil116 extends MCAChunk {
|
|||||||
private int[] biomes;
|
private int[] biomes;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ChunkAnvil116(CompoundTag chunkTag, boolean ignoreMissingLightData) {
|
public ChunkAnvil116(MCAWorld world, CompoundTag chunkTag) {
|
||||||
super(chunkTag);
|
super(world, chunkTag);
|
||||||
|
|
||||||
CompoundTag levelData = chunkTag.getCompoundTag("Level");
|
CompoundTag levelData = chunkTag.getCompoundTag("Level");
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ public ChunkAnvil116(CompoundTag chunkTag, boolean ignoreMissingLightData) {
|
|||||||
this.isGenerated = status.equals("full");
|
this.isGenerated = status.equals("full");
|
||||||
this.hasLight = isGenerated;
|
this.hasLight = isGenerated;
|
||||||
|
|
||||||
if (!isGenerated && ignoreMissingLightData) {
|
if (!isGenerated && getWorld().isIgnoreMissingLightData()) {
|
||||||
isGenerated = !status.equals("empty");
|
isGenerated = !status.equals("empty");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,12 +119,12 @@ public BlockState getBlockState(int x, int y, int z) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LightData getLightData(int x, int y, int z, LightData target) {
|
public LightData getLightData(int x, int y, int z, LightData target) {
|
||||||
if (!hasLight) return target.set(15, 0);
|
if (!hasLight) return target.set(getWorld().getSkyLight(), 0);
|
||||||
|
|
||||||
int sectionY = y >> 4;
|
int sectionY = y >> 4;
|
||||||
|
|
||||||
Section section = getSection(sectionY);
|
Section section = getSection(sectionY);
|
||||||
if (section == null) return (sectionY < sectionMin) ? target.set(0, 0) : target.set(15, 0);
|
if (section == null) return (sectionY < sectionMin) ? target.set(0, 0) : target.set(getWorld().getSkyLight(), 0);
|
||||||
|
|
||||||
return section.getLightData(x, y, z, target);
|
return section.getLightData(x, y, z, target);
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,21 @@
|
|||||||
|
|
||||||
public abstract class MCAChunk implements Chunk {
|
public abstract class MCAChunk implements Chunk {
|
||||||
|
|
||||||
|
private final MCAWorld world;
|
||||||
private final int dataVersion;
|
private final int dataVersion;
|
||||||
|
|
||||||
protected MCAChunk() {
|
protected MCAChunk() {
|
||||||
|
this.world = null;
|
||||||
|
this.dataVersion = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected MCAChunk(MCAWorld world) {
|
||||||
|
this.world = world;
|
||||||
this.dataVersion = -1;
|
this.dataVersion = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected MCAChunk(CompoundTag chunkTag) {
|
protected MCAChunk(MCAWorld world, CompoundTag chunkTag) {
|
||||||
|
this.world = world;
|
||||||
dataVersion = chunkTag.getInt("DataVersion");
|
dataVersion = chunkTag.getInt("DataVersion");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,13 +77,17 @@ public int getMaxY(int x, int z) {
|
|||||||
public int getMinY(int x, int z) {
|
public int getMinY(int x, int z) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MCAChunk create(MCAWorld world, CompoundTag chunkTag, boolean ignoreMissingLightData) throws IOException {
|
protected MCAWorld getWorld() {
|
||||||
|
return world;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static MCAChunk create(MCAWorld world, CompoundTag chunkTag) throws IOException {
|
||||||
int version = chunkTag.getInt("DataVersion");
|
int version = chunkTag.getInt("DataVersion");
|
||||||
|
|
||||||
if (version < 2200) return new ChunkAnvil113(chunkTag, ignoreMissingLightData);
|
if (version < 2200) return new ChunkAnvil113(world, chunkTag);
|
||||||
if (version < 2500) return new ChunkAnvil115(chunkTag, ignoreMissingLightData);
|
if (version < 2500) return new ChunkAnvil115(world, chunkTag);
|
||||||
return new ChunkAnvil116(chunkTag, ignoreMissingLightData);
|
return new ChunkAnvil116(world, chunkTag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MCAChunk empty() {
|
public static MCAChunk empty() {
|
||||||
@ -85,6 +97,7 @@ public static MCAChunk empty() {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "MCAChunk{" +
|
return "MCAChunk{" +
|
||||||
|
"world=" + world +
|
||||||
"dataVersion=" + dataVersion +
|
"dataVersion=" + dataVersion +
|
||||||
"isGenerated()=" + isGenerated() +
|
"isGenerated()=" + isGenerated() +
|
||||||
'}';
|
'}';
|
||||||
|
@ -84,7 +84,7 @@ public MCAChunk loadChunk(int chunkX, int chunkZ, boolean ignoreMissingLightData
|
|||||||
DataInputStream dis = new DataInputStream(new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD()))));
|
DataInputStream dis = new DataInputStream(new BufferedInputStream(compressionType.decompress(new FileInputStream(raf.getFD()))));
|
||||||
Tag<?> tag = Tag.deserialize(dis, Tag.DEFAULT_MAX_DEPTH);
|
Tag<?> tag = Tag.deserialize(dis, Tag.DEFAULT_MAX_DEPTH);
|
||||||
if (tag instanceof CompoundTag) {
|
if (tag instanceof CompoundTag) {
|
||||||
MCAChunk chunk = MCAChunk.create(world, (CompoundTag) tag, ignoreMissingLightData);
|
MCAChunk chunk = MCAChunk.create(world, (CompoundTag) tag);
|
||||||
if (!chunk.isGenerated()) return MCAChunk.empty();
|
if (!chunk.isGenerated()) return MCAChunk.empty();
|
||||||
return chunk;
|
return chunk;
|
||||||
} else {
|
} else {
|
||||||
|
@ -54,6 +54,7 @@ public class MCAWorld implements World {
|
|||||||
@DebugDump private final String name;
|
@DebugDump private final String name;
|
||||||
@DebugDump private final Vector3i spawnPoint;
|
@DebugDump private final Vector3i spawnPoint;
|
||||||
|
|
||||||
|
@DebugDump private final int skyLight;
|
||||||
@DebugDump private final boolean ignoreMissingLightData;
|
@DebugDump private final boolean ignoreMissingLightData;
|
||||||
|
|
||||||
private final LoadingCache<Vector2i, MCARegion> regionCache;
|
private final LoadingCache<Vector2i, MCARegion> regionCache;
|
||||||
@ -64,13 +65,15 @@ private MCAWorld(
|
|||||||
UUID uuid,
|
UUID uuid,
|
||||||
String name,
|
String name,
|
||||||
Vector3i spawnPoint,
|
Vector3i spawnPoint,
|
||||||
|
int skyLight,
|
||||||
boolean ignoreMissingLightData
|
boolean ignoreMissingLightData
|
||||||
) {
|
) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
this.worldFolder = worldFolder;
|
this.worldFolder = worldFolder;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.spawnPoint = spawnPoint;
|
this.spawnPoint = spawnPoint;
|
||||||
|
|
||||||
|
this.skyLight = skyLight;
|
||||||
this.ignoreMissingLightData = ignoreMissingLightData;
|
this.ignoreMissingLightData = ignoreMissingLightData;
|
||||||
|
|
||||||
this.regionCache = Caffeine.newBuilder()
|
this.regionCache = Caffeine.newBuilder()
|
||||||
@ -152,8 +155,8 @@ public Path getSaveFolder() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSeaLevel() {
|
public int getSkyLight() {
|
||||||
return 63;
|
return skyLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -203,7 +206,11 @@ public Path getWorldFolder() {
|
|||||||
private Path getRegionFolder() {
|
private Path getRegionFolder() {
|
||||||
return worldFolder.resolve("region");
|
return worldFolder.resolve("region");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isIgnoreMissingLightData() {
|
||||||
|
return ignoreMissingLightData;
|
||||||
|
}
|
||||||
|
|
||||||
private File getMCAFile(int regionX, int regionZ) {
|
private File getMCAFile(int regionX, int regionZ) {
|
||||||
return getRegionFolder().resolve("r." + regionX + "." + regionZ + ".mca").toFile();
|
return getRegionFolder().resolve("r." + regionX + "." + regionZ + ".mca").toFile();
|
||||||
}
|
}
|
||||||
@ -248,12 +255,8 @@ private MCAChunk loadChunk(int x, int z) {
|
|||||||
Logger.global.logDebug("Unexpected exception trying to load chunk (x:" + x + ", z:" + z + "):" + loadException);
|
Logger.global.logDebug("Unexpected exception trying to load chunk (x:" + x + ", z:" + z + "):" + loadException);
|
||||||
return MCAChunk.empty();
|
return MCAChunk.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MCAWorld load(Path worldFolder, UUID uuid) throws IOException {
|
|
||||||
return load(worldFolder, uuid, null, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MCAWorld load(Path worldFolder, UUID uuid, String name, boolean ignoreMissingLightData) throws IOException {
|
public static MCAWorld load(Path worldFolder, UUID uuid, String name, int skyLight, boolean ignoreMissingLightData) throws IOException {
|
||||||
try {
|
try {
|
||||||
StringBuilder subDimensionName = new StringBuilder();
|
StringBuilder subDimensionName = new StringBuilder();
|
||||||
|
|
||||||
@ -292,6 +295,7 @@ public static MCAWorld load(Path worldFolder, UUID uuid, String name, boolean ig
|
|||||||
uuid,
|
uuid,
|
||||||
name,
|
name,
|
||||||
spawnPoint,
|
spawnPoint,
|
||||||
|
skyLight,
|
||||||
ignoreMissingLightData
|
ignoreMissingLightData
|
||||||
);
|
);
|
||||||
} catch (ClassCastException | NullPointerException ex) {
|
} catch (ClassCastException | NullPointerException ex) {
|
||||||
|
@ -44,7 +44,7 @@ public static OutputStream createFilepartOutputStream(final Path file) throws IO
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Files.move(partFile, file, StandardCopyOption.ATOMIC_MOVE);
|
Files.move(partFile, file, StandardCopyOption.ATOMIC_MOVE);
|
||||||
} catch (AtomicMoveNotSupportedException ex) {
|
} catch (IOException ex) {
|
||||||
Files.move(partFile, file);
|
Files.move(partFile, file);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -24,30 +24,31 @@
|
|||||||
*/
|
*/
|
||||||
package de.bluecolored.bluemap.core.world;
|
package de.bluecolored.bluemap.core.world;
|
||||||
|
|
||||||
|
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
|
||||||
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
|
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
|
||||||
|
|
||||||
public class BlockNeighborhood<T extends BlockNeighborhood<T>> extends ResourcePackBlock<T> {
|
public class BlockNeighborhood<T extends BlockNeighborhood<T>> extends ExtendedBlock<T> {
|
||||||
|
|
||||||
private static final int DIAMETER = 8;
|
private static final int DIAMETER = 8;
|
||||||
private static final int DIAMETER_MASK = DIAMETER - 1;
|
private static final int DIAMETER_MASK = DIAMETER - 1;
|
||||||
private static final int DIAMETER_SQUARED = DIAMETER * DIAMETER;
|
private static final int DIAMETER_SQUARED = DIAMETER * DIAMETER;
|
||||||
|
|
||||||
private final ResourcePackBlock<?>[] neighborhood;
|
private final ExtendedBlock<?>[] neighborhood;
|
||||||
|
|
||||||
private int thisIndex;
|
private int thisIndex;
|
||||||
|
|
||||||
public BlockNeighborhood(ResourcePackBlock<?> center) {
|
public BlockNeighborhood(ExtendedBlock<?> center) {
|
||||||
super(center.getResourcePack(), null, 0, 0, 0);
|
super(center.getResourcePack(), center.getRenderSettings(), null, 0, 0, 0);
|
||||||
copy(center);
|
copy(center);
|
||||||
|
|
||||||
neighborhood = new ResourcePackBlock[DIAMETER * DIAMETER * DIAMETER];
|
neighborhood = new ExtendedBlock[DIAMETER * DIAMETER * DIAMETER];
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockNeighborhood(ResourcePack resourcePack, World world, int x, int y, int z) {
|
public BlockNeighborhood(ResourcePack resourcePack, RenderSettings renderSettings, World world, int x, int y, int z) {
|
||||||
super(resourcePack, world, x, y, z);
|
super(resourcePack, renderSettings, world, x, y, z);
|
||||||
|
|
||||||
neighborhood = new ResourcePackBlock[DIAMETER * DIAMETER * DIAMETER];
|
neighborhood = new ExtendedBlock[DIAMETER * DIAMETER * DIAMETER];
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,11 +62,11 @@ protected void reset() {
|
|||||||
private void init() {
|
private void init() {
|
||||||
this.thisIndex = -1;
|
this.thisIndex = -1;
|
||||||
for (int i = 0; i < neighborhood.length; i++) {
|
for (int i = 0; i < neighborhood.length; i++) {
|
||||||
neighborhood[i] = new ResourcePackBlock<>(this.getResourcePack(), null, 0, 0, 0);
|
neighborhood[i] = new ExtendedBlock<>(this.getResourcePack(), this.getRenderSettings(), null, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourcePackBlock<?> getNeighborBlock(int dx, int dy, int dz) {
|
public ExtendedBlock<?> getNeighborBlock(int dx, int dy, int dz) {
|
||||||
int i = neighborIndex(dx, dy, dz);
|
int i = neighborIndex(dx, dy, dz);
|
||||||
if (i == thisIndex()) return this;
|
if (i == thisIndex()) return this;
|
||||||
return neighborhood[i].set(
|
return neighborhood[i].set(
|
||||||
|
@ -24,19 +24,22 @@
|
|||||||
*/
|
*/
|
||||||
package de.bluecolored.bluemap.core.world;
|
package de.bluecolored.bluemap.core.world;
|
||||||
|
|
||||||
|
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
|
||||||
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
|
import de.bluecolored.bluemap.core.resourcepack.ResourcePack;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class ResourcePackBlock<T extends ResourcePackBlock<T>> extends Block<T> {
|
public class ExtendedBlock<T extends ExtendedBlock<T>> extends Block<T> {
|
||||||
|
|
||||||
private final ResourcePack resourcePack;
|
private final ResourcePack resourcePack;
|
||||||
|
private final RenderSettings renderSettings;
|
||||||
private BlockProperties properties;
|
private BlockProperties properties;
|
||||||
private Biome biome;
|
private Biome biome;
|
||||||
|
private Boolean insideRenderBounds;
|
||||||
|
|
||||||
public ResourcePackBlock(ResourcePack resourcePack, World world, int x, int y, int z) {
|
public ExtendedBlock(ResourcePack resourcePack, RenderSettings renderSettings, World world, int x, int y, int z) {
|
||||||
super(world, x, y, z);
|
super(world, x, y, z);
|
||||||
this.resourcePack = Objects.requireNonNull(resourcePack);
|
this.resourcePack = Objects.requireNonNull(resourcePack);
|
||||||
|
this.renderSettings = renderSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -45,6 +48,20 @@ protected void reset() {
|
|||||||
|
|
||||||
this.properties = null;
|
this.properties = null;
|
||||||
this.biome = null;
|
this.biome = null;
|
||||||
|
this.insideRenderBounds = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlockState() {
|
||||||
|
if (!isInsideRenderBounds() && renderSettings.isRenderEdges()) return BlockState.AIR;
|
||||||
|
return super.getBlockState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LightData getLightData() {
|
||||||
|
LightData ld = super.getLightData();
|
||||||
|
if (!isInsideRenderBounds() && renderSettings.isRenderEdges()) ld.set(getWorld().getSkyLight(), ld.getBlockLight());
|
||||||
|
return ld;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BlockProperties getProperties() {
|
public BlockProperties getProperties() {
|
||||||
@ -57,6 +74,15 @@ public Biome getBiome() {
|
|||||||
return biome;
|
return biome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RenderSettings getRenderSettings() {
|
||||||
|
return renderSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInsideRenderBounds() {
|
||||||
|
if (insideRenderBounds == null) insideRenderBounds = renderSettings.isInsideRenderBoundaries(getX(), getY(), getZ());
|
||||||
|
return insideRenderBounds;
|
||||||
|
}
|
||||||
|
|
||||||
public ResourcePack getResourcePack() {
|
public ResourcePack getResourcePack() {
|
||||||
return resourcePack;
|
return resourcePack;
|
||||||
}
|
}
|
@ -1,157 +0,0 @@
|
|||||||
/*
|
|
||||||
* This file is part of BlueMap, licensed under the MIT License (MIT).
|
|
||||||
*
|
|
||||||
* Copyright (c) Blue (Lukas Rieger) <https://bluecolored.de>
|
|
||||||
* Copyright (c) contributors
|
|
||||||
*
|
|
||||||
* 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 de.bluecolored.bluemap.core.world;
|
|
||||||
|
|
||||||
import com.flowpowered.math.vector.Vector2i;
|
|
||||||
import com.flowpowered.math.vector.Vector3i;
|
|
||||||
|
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A sliced view of a world. Everything outside the defined bounds is seen as "not generated" and "air".
|
|
||||||
*/
|
|
||||||
public class SlicedWorld implements World {
|
|
||||||
|
|
||||||
private final World world;
|
|
||||||
private final Vector3i min;
|
|
||||||
private final Vector3i max;
|
|
||||||
|
|
||||||
public SlicedWorld(World world, Vector3i min, Vector3i max) {
|
|
||||||
this.world = world;
|
|
||||||
this.min = min;
|
|
||||||
this.max = max;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return world.getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Path getSaveFolder() {
|
|
||||||
return world.getSaveFolder();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public UUID getUUID() {
|
|
||||||
return world.getUUID();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getSeaLevel() {
|
|
||||||
return world.getSeaLevel();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Vector3i getSpawnPoint() {
|
|
||||||
return world.getSpawnPoint();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMaxY(int x, int z) {
|
|
||||||
return world.getMaxY(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getMinY(int x, int z) {
|
|
||||||
return world.getMinY(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Grid getChunkGrid() {
|
|
||||||
return world.getChunkGrid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Grid getRegionGrid() {
|
|
||||||
return world.getRegionGrid();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Chunk getChunk(int x, int z) {
|
|
||||||
return world.getChunk(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Chunk getChunkAtBlock(int x, int y, int z) {
|
|
||||||
return world.getChunkAtBlock(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Region getRegion(int x, int z) {
|
|
||||||
return world.getRegion(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<Vector2i> listRegions() {
|
|
||||||
Grid regionGrid = getRegionGrid();
|
|
||||||
Collection<Vector2i> regions = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Vector2i region : world.listRegions()) {
|
|
||||||
Vector2i min = regionGrid.getCellMin(region);
|
|
||||||
Vector2i max = regionGrid.getCellMax(region);
|
|
||||||
if (isInside(min.getX(), min.getY()) || isInside(max.getX(), max.getY())) regions.add(region);
|
|
||||||
}
|
|
||||||
|
|
||||||
return regions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateChunkCache() {
|
|
||||||
world.invalidateChunkCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateChunkCache(int x, int z) {
|
|
||||||
world.invalidateChunkCache(x, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void cleanUpChunkCache() {
|
|
||||||
world.cleanUpChunkCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInside(int x, int z) {
|
|
||||||
return
|
|
||||||
x >= min.getX() &&
|
|
||||||
x <= max.getX() &&
|
|
||||||
z >= min.getZ() &&
|
|
||||||
z <= max.getZ();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInside(int x, int y, int z) {
|
|
||||||
return
|
|
||||||
x >= min.getX() &&
|
|
||||||
x <= max.getX() &&
|
|
||||||
z >= min.getZ() &&
|
|
||||||
z <= max.getZ() &&
|
|
||||||
y >= min.getY() &&
|
|
||||||
y <= max.getY();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -43,8 +43,8 @@ public interface World {
|
|||||||
UUID getUUID();
|
UUID getUUID();
|
||||||
|
|
||||||
Path getSaveFolder();
|
Path getSaveFolder();
|
||||||
|
|
||||||
int getSeaLevel();
|
int getSkyLight();
|
||||||
|
|
||||||
Vector3i getSpawnPoint();
|
Vector3i getSpawnPoint();
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public Collection<SpongeCommandProxy> getRootCommands(){
|
|||||||
|
|
||||||
public class SpongeCommandProxy implements Command.Raw {
|
public class SpongeCommandProxy implements Command.Raw {
|
||||||
|
|
||||||
private String label;
|
private final String label;
|
||||||
|
|
||||||
protected SpongeCommandProxy(String label) {
|
protected SpongeCommandProxy(String label) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
@ -88,12 +88,13 @@ public CommandResult process(CommandCause cause, ArgumentReader.Mutable argument
|
|||||||
try {
|
try {
|
||||||
return CommandResult.builder().result(dispatcher.execute(command, cause)).build();
|
return CommandResult.builder().result(dispatcher.execute(command, cause)).build();
|
||||||
} catch (CommandSyntaxException ex) {
|
} catch (CommandSyntaxException ex) {
|
||||||
cause.audience().sendMessage(Component.text(ex.getRawMessage().getString(), NamedTextColor.RED));
|
Component errText = Component.text(ex.getRawMessage().getString(), NamedTextColor.RED);
|
||||||
|
|
||||||
String context = ex.getContext();
|
String context = ex.getContext();
|
||||||
if (context != null) cause.audience().sendMessage(Component.text(context, NamedTextColor.GRAY));
|
if (context != null)
|
||||||
|
errText = errText.append(Component.newline()).append(Component.text(context, NamedTextColor.GRAY));
|
||||||
|
|
||||||
return CommandResult.empty();
|
return CommandResult.error(errText);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +36,10 @@
|
|||||||
import de.bluecolored.bluemap.core.logger.Logger;
|
import de.bluecolored.bluemap.core.logger.Logger;
|
||||||
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
|
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
|
||||||
import de.bluecolored.bluemap.sponge8.SpongeCommands.SpongeCommandProxy;
|
import de.bluecolored.bluemap.sponge8.SpongeCommands.SpongeCommandProxy;
|
||||||
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
|
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||||
import net.querz.nbt.CompoundTag;
|
import net.querz.nbt.CompoundTag;
|
||||||
import net.querz.nbt.NBTUtil;
|
import net.querz.nbt.NBTUtil;
|
||||||
|
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
||||||
import org.spongepowered.api.Platform;
|
import org.spongepowered.api.Platform;
|
||||||
import org.spongepowered.api.Server;
|
import org.spongepowered.api.Server;
|
||||||
import org.spongepowered.api.Sponge;
|
import org.spongepowered.api.Sponge;
|
||||||
@ -65,7 +66,7 @@
|
|||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
@org.spongepowered.plugin.jvm.Plugin(Plugin.PLUGIN_ID)
|
@org.spongepowered.plugin.builtin.jvm.Plugin(Plugin.PLUGIN_ID)
|
||||||
public class SpongePlugin implements ServerInterface {
|
public class SpongePlugin implements ServerInterface {
|
||||||
|
|
||||||
private final PluginContainer pluginContainer;
|
private final PluginContainer pluginContainer;
|
||||||
@ -92,13 +93,12 @@ public SpongePlugin(org.apache.logging.log4j.Logger logger, PluginContainer plug
|
|||||||
this.onlinePlayerMap = new ConcurrentHashMap<>();
|
this.onlinePlayerMap = new ConcurrentHashMap<>();
|
||||||
this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>());
|
this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>());
|
||||||
|
|
||||||
final String versionFromSponge = Sponge.platform().container(Platform.Component.GAME).metadata().version();
|
final ArtifactVersion versionFromSponge = Sponge.platform().container(Platform.Component.GAME).metadata().version();
|
||||||
MinecraftVersion version = new MinecraftVersion(1, 16);
|
MinecraftVersion version = new MinecraftVersion(
|
||||||
try {
|
versionFromSponge.getMajorVersion(),
|
||||||
version = MinecraftVersion.of(versionFromSponge);
|
versionFromSponge.getMinorVersion(),
|
||||||
} catch (IllegalArgumentException e) {
|
versionFromSponge.getIncrementalVersion()
|
||||||
Logger.global.logWarning("Failed to find a matching version for version-name '" + versionFromSponge + "'! Using latest known sponge-version: " + version.getVersionString());
|
);
|
||||||
}
|
|
||||||
|
|
||||||
this.pluginInstance = new Plugin(version, "sponge-8.0.0", this);
|
this.pluginInstance = new Plugin(version, "sponge-8.0.0", this);
|
||||||
this.commands = new SpongeCommands(pluginInstance);
|
this.commands = new SpongeCommands(pluginInstance);
|
||||||
@ -210,7 +210,7 @@ public String getWorldName(UUID worldUUID) {
|
|||||||
serverWorld -> serverWorld
|
serverWorld -> serverWorld
|
||||||
.properties()
|
.properties()
|
||||||
.displayName()
|
.displayName()
|
||||||
.map(PlainComponentSerializer.plain()::serialize)
|
.map(PlainTextComponentSerializer.plainText()::serialize)
|
||||||
)
|
)
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user