diff --git a/buildSrc/src/main/kotlin/bluemap.base.gradle.kts b/buildSrc/src/main/kotlin/bluemap.base.gradle.kts
index 078ba7bd0..9aeab70c3 100644
--- a/buildSrc/src/main/kotlin/bluemap.base.gradle.kts
+++ b/buildSrc/src/main/kotlin/bluemap.base.gradle.kts
@@ -10,7 +10,7 @@ version = gitVersion()
repositories {
maven ("https://repo.bluecolored.de/releases") {
- content { includeGroupByRegex ("de\\.bluecolored\\..*") }
+ content { includeGroupByRegex ("de\\.bluecolored.*") }
}
maven ("https://hub.spigotmc.org/nexus/content/repositories/snapshots/") {
content { includeGroup ("org.spigotmc") }
diff --git a/common/src/main/java/de/bluecolored/bluemap/common/plugin/commands/Commands.java b/common/src/main/java/de/bluecolored/bluemap/common/plugin/commands/Commands.java
index dde0796c2..0bba2e68b 100644
--- a/common/src/main/java/de/bluecolored/bluemap/common/plugin/commands/Commands.java
+++ b/common/src/main/java/de/bluecolored/bluemap/common/plugin/commands/Commands.java
@@ -55,11 +55,11 @@
import de.bluecolored.bluemap.core.storage.MapStorage;
import de.bluecolored.bluemap.core.storage.Storage;
import de.bluecolored.bluemap.core.util.Grid;
+import de.bluecolored.bluemap.core.world.BlockEntity;
import de.bluecolored.bluemap.core.world.Chunk;
import de.bluecolored.bluemap.core.world.ChunkConsumer;
import de.bluecolored.bluemap.core.world.World;
import de.bluecolored.bluemap.core.world.block.Block;
-import de.bluecolored.bluemap.core.world.block.entity.BlockEntity;
import java.io.IOException;
import java.nio.file.Path;
@@ -594,8 +594,8 @@ public int debugBlockCommand(CommandContext context) {
new Thread(() -> {
// collect and output debug info
Vector3i blockPos = position.floor().toInt();
- Block> block = new Block<>(world, blockPos.getX(), blockPos.getY(), blockPos.getZ());
- Block> blockBelow = new Block<>(world, blockPos.getX(), blockPos.getY() - 1, blockPos.getZ());
+ Block block = new Block(world, blockPos.getX(), blockPos.getY(), blockPos.getZ());
+ Block blockBelow = new Block(world, blockPos.getX(), blockPos.getY() - 1, blockPos.getZ());
source.sendMessages(Arrays.asList(
Text.of(TextColor.GOLD, "Block at you: \n", formatBlock(block)),
@@ -606,7 +606,7 @@ public int debugBlockCommand(CommandContext context) {
return 1;
}
- private Text formatBlock(Block> block) {
+ private Text formatBlock(Block block) {
World world = block.getWorld();
Chunk chunk = block.getChunk();
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/HiresModelRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/HiresModelRenderer.java
index b6c6e89d5..a25a76e99 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/HiresModelRenderer.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/HiresModelRenderer.java
@@ -24,14 +24,17 @@
*/
package de.bluecolored.bluemap.core.map.hires;
+import com.flowpowered.math.vector.Vector3d;
import com.flowpowered.math.vector.Vector3i;
import de.bluecolored.bluemap.core.map.TextureGallery;
import de.bluecolored.bluemap.core.map.TileMetaConsumer;
-import de.bluecolored.bluemap.core.map.hires.blockmodel.BlockStateModelRenderer;
+import de.bluecolored.bluemap.core.map.hires.block.BlockStateModelRenderer;
+import de.bluecolored.bluemap.core.map.hires.entity.EntityModelRenderer;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.util.math.Color;
import de.bluecolored.bluemap.core.world.Chunk;
import de.bluecolored.bluemap.core.world.World;
+import de.bluecolored.bluemap.core.world.block.Block;
import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
public class HiresModelRenderer {
@@ -40,12 +43,14 @@ public class HiresModelRenderer {
private final RenderSettings renderSettings;
private final ThreadLocal threadLocalBlockRenderer;
+ private final ThreadLocal threadLocalEntityRenderer;
public HiresModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) {
this.resourcePack = resourcePack;
this.renderSettings = renderSettings;
this.threadLocalBlockRenderer = ThreadLocal.withInitial(() -> new BlockStateModelRenderer(resourcePack, textureGallery, renderSettings));
+ this.threadLocalEntityRenderer = ThreadLocal.withInitial(() -> new EntityModelRenderer(resourcePack, textureGallery, renderSettings));
}
public void render(World world, Vector3i modelMin, Vector3i modelMax, TileModel model) {
@@ -57,13 +62,15 @@ public void render(World world, Vector3i modelMin, Vector3i modelMax, TileModel
Vector3i max = modelMax.min(renderSettings.getMaxPos());
Vector3i modelAnchor = new Vector3i(modelMin.getX(), 0, modelMin.getZ());
+ // render blocks
BlockStateModelRenderer blockRenderer = threadLocalBlockRenderer.get();
+ EntityModelRenderer entityRenderer = threadLocalEntityRenderer.get();
int maxHeight, minY, maxY;
double topBlockLight;
Color columnColor = new Color(), blockColor = new Color();
- BlockNeighborhood> block = new BlockNeighborhood<>(resourcePack, renderSettings, world, 0, 0, 0);
- TileModelView blockModel = new TileModelView(tileModel);
+ BlockNeighborhood block = new BlockNeighborhood(new Block(world, 0, 0, 0), resourcePack, renderSettings, world.getDimensionType());
+ TileModelView tileModelView = new TileModelView(tileModel);
int x, y, z;
for (x = modelMin.getX(); x <= modelMax.getX(); x++){
@@ -80,18 +87,21 @@ public void render(World world, Vector3i modelMin, Vector3i modelMax, TileModel
maxY = Math.min(max.getY(), chunk.getMaxY(x, z));
for (y = maxY; y >= minY; y--) {
+ if (x == -1743 && y == 64 && z == 1393)
+ System.out.println();
+
block.set(x, y, z);
if (!block.isInsideRenderBounds()) continue;
- blockModel.initialize();
+ tileModelView.initialize();
- blockRenderer.render(block, blockModel, blockColor);
+ blockRenderer.render(block, tileModelView, blockColor);
//update topBlockLight
topBlockLight = Math.max(topBlockLight, block.getBlockLightLevel() * (1 - columnColor.a));
// move block-model to correct position
- blockModel.translate(x - modelAnchor.getX(), y - modelAnchor.getY(), z - modelAnchor.getZ());
+ tileModelView.translate(x - modelAnchor.getX(), y - modelAnchor.getY(), z - modelAnchor.getZ());
//update color and height (only if not 100% translucent)
if (blockColor.a > 0) {
@@ -110,5 +120,18 @@ public void render(World world, Vector3i modelMin, Vector3i modelMax, TileModel
tileMetaConsumer.set(x, z, columnColor, maxHeight, (int) topBlockLight);
}
}
+
+ // render entities
+ world.iterateEntities(min.getX(), min.getZ(), max.getX(), max.getZ(), entity -> {
+ Vector3d pos = entity.getPos();
+ block.set(pos.getFloorX(), pos.getFloorY(), pos.getFloorZ());
+ entityRenderer.render(entity, block, tileModelView.initialize());
+ tileModelView.translate(
+ (float) pos.getX() - modelAnchor.getX(),
+ (float) pos.getY() - modelAnchor.getY(),
+ (float) pos.getZ() - modelAnchor.getZ()
+ );
+ });
+
}
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRenderer.java
similarity index 90%
rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRenderer.java
rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRenderer.java
index f86ba69a2..c45151507 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRenderer.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRenderer.java
@@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.map.hires.blockmodel;
+package de.bluecolored.bluemap.core.map.hires.block;
import de.bluecolored.bluemap.core.map.hires.TileModelView;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockstate.Variant;
@@ -43,9 +43,9 @@ public interface BlockRenderer {
*
* @param block The block information that should be rendered.
* @param variant The block-state variant that should be rendered.
- * @param blockModel The model(-view) where the block should be rendered to.
+ * @param tileModel The model(-view) where the block should be rendered to.
* @param blockColor The color that should be set to the color that represents the rendered block.
*/
- void render(BlockNeighborhood> block, Variant variant, TileModelView blockModel, Color blockColor);
+ void render(BlockNeighborhood block, Variant variant, TileModelView tileModel, Color blockColor);
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRendererFactory.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRendererFactory.java
similarity index 96%
rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRendererFactory.java
rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRendererFactory.java
index e6a31259c..e219d7731 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRendererFactory.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRendererFactory.java
@@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.map.hires.blockmodel;
+package de.bluecolored.bluemap.core.map.hires.block;
import de.bluecolored.bluemap.core.map.TextureGallery;
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRendererType.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRendererType.java
similarity index 98%
rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRendererType.java
rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRendererType.java
index 82622f343..f6139565d 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRendererType.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockRendererType.java
@@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.map.hires.blockmodel;
+package de.bluecolored.bluemap.core.map.hires.block;
import de.bluecolored.bluemap.core.map.TextureGallery;
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockStateModelRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockStateModelRenderer.java
similarity index 77%
rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockStateModelRenderer.java
rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockStateModelRenderer.java
index ae2d93c38..2d4a2580c 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockStateModelRenderer.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/BlockStateModelRenderer.java
@@ -22,19 +22,18 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.map.hires.blockmodel;
+package de.bluecolored.bluemap.core.map.hires.block;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import de.bluecolored.bluemap.core.map.TextureGallery;
-import de.bluecolored.bluemap.core.map.hires.TileModelView;
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
+import de.bluecolored.bluemap.core.map.hires.TileModelView;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.BlockModel;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockstate.Variant;
import de.bluecolored.bluemap.core.util.math.Color;
-import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
import de.bluecolored.bluemap.core.world.BlockState;
+import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
import java.util.ArrayList;
import java.util.List;
@@ -52,35 +51,35 @@ public BlockStateModelRenderer(ResourcePack resourcePack, TextureGallery texture
.build(type -> type.create(resourcePack, textureGallery, renderSettings));
}
- public void render(BlockNeighborhood> block, TileModelView blockModel, Color blockColor) {
+ public void render(BlockNeighborhood block, TileModelView blockModel, Color blockColor) {
render(block, block.getBlockState(), blockModel, blockColor);
}
private final Color waterloggedColor = new Color();
- public void render(BlockNeighborhood> block, BlockState blockState, TileModelView blockModel, Color blockColor) {
+ public void render(BlockNeighborhood block, BlockState blockState, TileModelView tileModel, Color blockColor) {
blockColor.set(0, 0, 0, 0, true);
//shortcut for air
if (blockState.isAir()) return;
- int modelStart = blockModel.getStart();
+ int modelStart = tileModel.getStart();
// render block
- renderModel(block, blockState, blockModel.initialize(), blockColor);
+ renderModel(block, blockState, tileModel.initialize(), blockColor);
// add water if block is waterlogged
if (blockState.isWaterlogged() || block.getProperties().isAlwaysWaterlogged()) {
waterloggedColor.set(0f, 0f, 0f, 0f, true);
- renderModel(block, WATERLOGGED_BLOCKSTATE, blockModel.initialize(), waterloggedColor);
+ renderModel(block, WATERLOGGED_BLOCKSTATE, tileModel.initialize(), waterloggedColor);
blockColor.set(waterloggedColor.overlay(blockColor.premultiplied()));
}
- blockModel.initialize(modelStart);
+ tileModel.initialize(modelStart);
}
private final Color variantColor = new Color();
- private void renderModel(BlockNeighborhood> block, BlockState blockState, TileModelView blockModel, Color blockColor) {
- int modelStart = blockModel.getStart();
+ private void renderModel(BlockNeighborhood block, BlockState blockState, TileModelView tileModel, Color blockColor) {
+ int modelStart = tileModel.getStart();
var stateResource = resourcePack.getBlockState(blockState);
if (stateResource == null) return;
@@ -91,19 +90,14 @@ private void renderModel(BlockNeighborhood> block, BlockState blockState, Tile
//noinspection ForLoopReplaceableByForEach
for (int i = 0; i < variants.size(); i++) {
- Variant variant = variants.get(i);
-
- BlockModel modelResource = variant.getModel().getResource(resourcePack::getBlockModel);
- if (modelResource == null) continue;
-
variantColor.set(0f, 0f, 0f, 0f, true);
- blockRenderers.get(modelResource.getRenderer())
- .render(block, variant, blockModel.initialize(), variantColor);
+ Variant variant = variants.get(i);
+ blockRenderers.get(variant.getRenderer())
+ .render(block, variant, tileModel.initialize(), variantColor);
if (variantColor.a > blockColorOpacity)
blockColorOpacity = variantColor.a;
-
blockColor.add(variantColor.premultiplied());
}
@@ -112,7 +106,7 @@ private void renderModel(BlockNeighborhood> block, BlockState blockState, Tile
blockColor.a = blockColorOpacity;
}
- blockModel.initialize(modelStart);
+ tileModel.initialize(modelStart);
}
private final static BlockState WATERLOGGED_BLOCKSTATE = new BlockState("minecraft:water");
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/LiquidModelRenderer.java
similarity index 95%
rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelRenderer.java
rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/LiquidModelRenderer.java
index a26e66e56..d44adf63f 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelRenderer.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/LiquidModelRenderer.java
@@ -22,19 +22,19 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.map.hires.blockmodel;
+package de.bluecolored.bluemap.core.map.hires.block;
import com.flowpowered.math.TrigMath;
import com.flowpowered.math.vector.Vector3i;
import de.bluecolored.bluemap.core.map.TextureGallery;
-import de.bluecolored.bluemap.core.map.hires.TileModelView;
-import de.bluecolored.bluemap.core.map.hires.TileModel;
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
+import de.bluecolored.bluemap.core.map.hires.TileModel;
+import de.bluecolored.bluemap.core.map.hires.TileModelView;
import de.bluecolored.bluemap.core.resources.BlockColorCalculatorFactory;
import de.bluecolored.bluemap.core.resources.ResourcePath;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.BlockModel;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.TextureVariable;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Model;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.TextureVariable;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockstate.Variant;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.texture.Texture;
import de.bluecolored.bluemap.core.util.Direction;
@@ -42,8 +42,8 @@
import de.bluecolored.bluemap.core.util.math.MatrixM3f;
import de.bluecolored.bluemap.core.util.math.VectorM2f;
import de.bluecolored.bluemap.core.util.math.VectorM3f;
-import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
import de.bluecolored.bluemap.core.world.BlockState;
+import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
import de.bluecolored.bluemap.core.world.block.ExtendedBlock;
/**
@@ -66,10 +66,10 @@ public class LiquidModelRenderer implements BlockRenderer {
private final VectorM3f[] corners;
private final VectorM2f[] uvs = new VectorM2f[4];
- private BlockNeighborhood> block;
+ private BlockNeighborhood block;
private BlockState blockState;
private boolean isWaterlogged, isWaterLike;
- private BlockModel modelResource;
+ private Model modelResource;
private TileModelView blockModel;
private Color blockColor;
@@ -93,15 +93,17 @@ public LiquidModelRenderer(ResourcePack resourcePack, TextureGallery textureGall
for (int i = 0; i < uvs.length; i++) uvs[i] = new VectorM2f(0, 0);
}
- public void render(BlockNeighborhood> block, Variant variant, TileModelView blockModel, Color color) {
+ public void render(BlockNeighborhood block, Variant variant, TileModelView blockModel, Color color) {
this.block = block;
this.blockState = block.getBlockState();
this.isWaterlogged = blockState.isWaterlogged() || block.getProperties().isAlwaysWaterlogged();
this.isWaterLike = blockState.isWater() || isWaterlogged;
- this.modelResource = variant.getModel().getResource();
+ this.modelResource = variant.getModel().getResource(resourcePack::getModel);
this.blockModel = blockModel;
this.blockColor = color;
+ if (this.modelResource == null) return;
+
build();
}
@@ -191,7 +193,7 @@ private float getLiquidCornerHeight(int x, int z){
float sumHeight = 0f;
int count = 0;
- ExtendedBlock> neighbor;
+ ExtendedBlock neighbor;
BlockState neighborBlockState;
for (ix = x; ix <= x+1; ix++){
@@ -223,7 +225,7 @@ private boolean isLiquidBlockingBlock(BlockState blockState){
}
@SuppressWarnings("StringEquality")
- private boolean isSameLiquid(ExtendedBlock> block){
+ private boolean isSameLiquid(ExtendedBlock block){
BlockState blockState = block.getBlockState();
if (this.isWaterlogged)
@@ -245,7 +247,7 @@ private boolean createElementFace(Direction faceDir, VectorM3f c0, VectorM3f c1,
Vector3i faceDirVector = faceDir.toVector();
//face culling
- ExtendedBlock> bl = block.getNeighborBlock(
+ ExtendedBlock bl = block.getNeighborBlock(
faceDirVector.getX(),
faceDirVector.getY(),
faceDirVector.getZ()
@@ -369,7 +371,7 @@ private int getFlowingAngle() {
}
private float compareLiquidHeights(float ownHeight, int dx, int dz) {
- ExtendedBlock> neighbor = block.getNeighborBlock(dx, 0, dz);
+ ExtendedBlock neighbor = block.getNeighborBlock(dx, 0, dz);
if (neighbor.getBlockState().isAir()) return 0;
if (!isSameLiquid(neighbor)) return 0;
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/MissingModelRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/MissingModelRenderer.java
similarity index 94%
rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/MissingModelRenderer.java
rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/MissingModelRenderer.java
index b18d43056..31e22d6f1 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/MissingModelRenderer.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/MissingModelRenderer.java
@@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.map.hires.blockmodel;
+package de.bluecolored.bluemap.core.map.hires.block;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
@@ -56,7 +56,7 @@ public MissingModelRenderer(ResourcePack resourcePack, TextureGallery textureGal
}
@Override
- public void render(BlockNeighborhood> block, Variant variant, TileModelView blockModel, Color blockColor) {
+ public void render(BlockNeighborhood block, Variant variant, TileModelView blockModel, Color blockColor) {
blockRenderers.get(BLOCK_RENDERER_TYPES.get(block.getBlockState()))
.render(block, variant, blockModel, blockColor);
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/ResourceModelRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/ResourceModelRenderer.java
similarity index 90%
rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/ResourceModelRenderer.java
rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/ResourceModelRenderer.java
index 286f23099..3abc93c55 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/ResourceModelRenderer.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/block/ResourceModelRenderer.java
@@ -22,23 +22,23 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.map.hires.blockmodel;
+package de.bluecolored.bluemap.core.map.hires.block;
import com.flowpowered.math.TrigMath;
import com.flowpowered.math.vector.Vector3f;
import com.flowpowered.math.vector.Vector3i;
import com.flowpowered.math.vector.Vector4f;
import de.bluecolored.bluemap.core.map.TextureGallery;
-import de.bluecolored.bluemap.core.map.hires.TileModelView;
-import de.bluecolored.bluemap.core.map.hires.TileModel;
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
+import de.bluecolored.bluemap.core.map.hires.TileModel;
+import de.bluecolored.bluemap.core.map.hires.TileModelView;
import de.bluecolored.bluemap.core.resources.BlockColorCalculatorFactory;
import de.bluecolored.bluemap.core.resources.ResourcePath;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.BlockModel;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.Element;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.Face;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockstate.Variant;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Element;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Face;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Model;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.texture.Texture;
import de.bluecolored.bluemap.core.util.Direction;
import de.bluecolored.bluemap.core.util.math.Color;
@@ -68,9 +68,9 @@ public class ResourceModelRenderer implements BlockRenderer {
private final Color tintColor = new Color();
private final Color mapColor = new Color();
- private BlockNeighborhood> block;
+ private BlockNeighborhood block;
private Variant variant;
- private BlockModel modelResource;
+ private Model modelResource;
private TileModelView blockModel;
private Color blockColor;
private float blockColorOpacity;
@@ -85,14 +85,15 @@ public ResourceModelRenderer(ResourcePack resourcePack, TextureGallery textureGa
for (int i = 0; i < rawUvs.length; i++) rawUvs[i] = new VectorM2f(0, 0);
}
- private final MatrixM4f modelTransform = new MatrixM4f();
- public void render(BlockNeighborhood> block, Variant variant, TileModelView blockModel, Color color) {
+ public void render(BlockNeighborhood block, Variant variant, TileModelView blockModel, Color color) {
this.block = block;
this.blockModel = blockModel;
this.blockColor = color;
this.blockColorOpacity = 0f;
this.variant = variant;
- this.modelResource = variant.getModel().getResource();
+ this.modelResource = variant.getModel().getResource(resourcePack::getModel);
+
+ if (this.modelResource == null) return;
this.tintColor.set(0, 0, 0, -1, true);
@@ -113,14 +114,9 @@ public void render(BlockNeighborhood> block, Variant variant, TileModelView bl
blockModel.initialize(modelStart);
- // apply model-rotation
- if (variant.isRotated()) {
- blockModel.transform(modelTransform.identity()
- .translate(-0.5f, -0.5f, -0.5f)
- .multiplyTo(variant.getRotationMatrix())
- .translate(0.5f, 0.5f, 0.5f)
- );
- }
+ // apply model-transform
+ if (variant.isTransformed())
+ blockModel.transform(variant.getTransformMatrix());
//random offset
if (block.getProperties().isRandomOffset()){
@@ -180,7 +176,7 @@ private void createElementFace(Element element, Direction faceDir, VectorM3f c0,
Vector3i faceDirVector = faceDir.toVector();
// light calculation
- ExtendedBlock> facedBlockNeighbor = getRotationRelativeBlock(faceDir);
+ ExtendedBlock facedBlockNeighbor = getRotationRelativeBlock(faceDir);
LightData blockLightData = block.getLightData();
LightData facedLightData = facedBlockNeighbor.getLightData();
@@ -205,7 +201,7 @@ private void createElementFace(Element element, Direction faceDir, VectorM3f c0,
// face culling
if (renderSettings.isRenderTopOnly() && faceRotationVector.y < 0.01) return;
if (face.getCullface() != null) {
- ExtendedBlock> b = getRotationRelativeBlock(face.getCullface());
+ ExtendedBlock b = getRotationRelativeBlock(face.getCullface());
BlockProperties p = b.getProperties();
if (p.isCulling()) return;
if (p.getCullingIdentical() && b.getBlockState().equals(block.getBlockState())) return;
@@ -258,7 +254,7 @@ private void createElementFace(Element element, Direction faceDir, VectorM3f c0,
// UV-Lock counter-rotation
float uvRotation = 0f;
- if (variant.isUvlock() && variant.isRotated()) {
+ if (variant.isUvlock() && variant.isTransformed()) {
float xRotSin = TrigMath.sin(variant.getX() * TrigMath.DEG_TO_RAD);
float xRotCos = TrigMath.cos(variant.getX() * TrigMath.DEG_TO_RAD);
@@ -300,8 +296,8 @@ private void createElementFace(Element element, Direction faceDir, VectorM3f c0,
tileModel.setColor(face1, tintColor.r, tintColor.g, tintColor.b);
tileModel.setColor(face2, tintColor.r, tintColor.g, tintColor.b);
} else {
- tileModel.setColor(face1, 1, 1, 1);
- tileModel.setColor(face2, 1, 1, 1);
+ tileModel.setColor(face1, 1f, 1f, 1f);
+ tileModel.setColor(face2, 1f, 1f, 1f);
}
// ####### blocklight
@@ -350,11 +346,11 @@ private void createElementFace(Element element, Direction faceDir, VectorM3f c0,
}
}
- private ExtendedBlock> getRotationRelativeBlock(Direction direction){
+ private ExtendedBlock getRotationRelativeBlock(Direction direction){
return getRotationRelativeBlock(direction.toVector());
}
- private ExtendedBlock> getRotationRelativeBlock(Vector3i direction){
+ private ExtendedBlock getRotationRelativeBlock(Vector3i direction){
return getRotationRelativeBlock(
direction.getX(),
direction.getY(),
@@ -363,7 +359,7 @@ private ExtendedBlock> getRotationRelativeBlock(Vector3i direction){
}
private final VectorM3f rotationRelativeBlockDirection = new VectorM3f(0, 0, 0);
- private ExtendedBlock> getRotationRelativeBlock(int dx, int dy, int dz){
+ private ExtendedBlock getRotationRelativeBlock(int dx, int dy, int dz){
rotationRelativeBlockDirection.set(dx, dy, dz);
makeRotationRelative(rotationRelativeBlockDirection);
@@ -375,8 +371,8 @@ private ExtendedBlock> getRotationRelativeBlock(int dx, int dy, int dz){
}
private void makeRotationRelative(VectorM3f direction){
- if (variant.isRotated())
- direction.transform(variant.getRotationMatrix());
+ if (variant.isTransformed())
+ direction.rotateAndScale(variant.getTransformMatrix());
}
private float testAo(VectorM3f vertex, Direction dir){
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityModelRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityModelRenderer.java
new file mode 100644
index 000000000..ebcb9f80b
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityModelRenderer.java
@@ -0,0 +1,71 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.map.hires.entity;
+
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.LoadingCache;
+import de.bluecolored.bluemap.core.map.TextureGallery;
+import de.bluecolored.bluemap.core.map.hires.RenderSettings;
+import de.bluecolored.bluemap.core.map.hires.TileModelView;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.entitystate.EntityState;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.entitystate.Part;
+import de.bluecolored.bluemap.core.world.Entity;
+import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
+
+public class EntityModelRenderer {
+
+ private final ResourcePack resourcePack;
+ private final LoadingCache entityRenderers;
+
+ public EntityModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) {
+ this.resourcePack = resourcePack;
+ this.entityRenderers = Caffeine.newBuilder()
+ .build(type -> type.create(resourcePack, textureGallery, renderSettings));
+ }
+
+ public void render(Entity entity, BlockNeighborhood block, TileModelView tileModel) {
+ EntityState stateResource = resourcePack.getEntityState(entity.getId());
+ if (stateResource == null) return;
+
+ Part[] parts = stateResource.getParts();
+ if (parts.length == 0) return;
+
+ int modelStart = tileModel.getStart();
+
+ //noinspection ForLoopReplaceableByForEach
+ for (int i = 0; i < parts.length; i++) {
+ Part part = parts[i];
+ entityRenderers.get(part.getRenderer())
+ .render(entity, block, part, tileModel.initialize());
+ }
+
+ tileModel.initialize(modelStart);
+
+ // apply entity rotation
+ tileModel.rotate(entity.getRotation().getY(), entity.getRotation().getX(), 0f);
+ }
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRenderer.java
new file mode 100644
index 000000000..b3adac7ea
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRenderer.java
@@ -0,0 +1,50 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.map.hires.entity;
+
+import de.bluecolored.bluemap.core.map.hires.TileModelView;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.entitystate.Part;
+import de.bluecolored.bluemap.core.world.Entity;
+import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
+
+public interface EntityRenderer {
+
+ /**
+ * Renders the given entities part into the given model.
+ *
+ * Implementation Note:
+ * This method is guaranteed to be called only on one thread per EntityRenderer instance, so you can use this
+ * for optimizations.
+ * Keep in mind this method will be called once for every block that is being rendered, so be very careful
+ * about performance and instance-creations.
+ *
+ * @param entity The entity information that should be rendered.
+ * @param block the block-position the entity lives at.
+ * @param part The entity part that should be rendered.
+ * @param tileModel The model(-view) where the block should be rendered to.
+ */
+ void render(Entity entity, BlockNeighborhood block, Part part, TileModelView tileModel);
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRendererFactory.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRendererFactory.java
new file mode 100644
index 000000000..cc1a1c76e
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRendererFactory.java
@@ -0,0 +1,35 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.map.hires.entity;
+
+import de.bluecolored.bluemap.core.map.TextureGallery;
+import de.bluecolored.bluemap.core.map.hires.RenderSettings;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
+
+public interface EntityRendererFactory {
+
+ EntityRenderer create(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings);
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRendererType.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRendererType.java
new file mode 100644
index 000000000..07309ae69
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/EntityRendererType.java
@@ -0,0 +1,77 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.map.hires.entity;
+
+import de.bluecolored.bluemap.core.map.TextureGallery;
+import de.bluecolored.bluemap.core.map.hires.RenderSettings;
+import de.bluecolored.bluemap.core.map.hires.block.LiquidModelRenderer;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
+import de.bluecolored.bluemap.core.util.Key;
+import de.bluecolored.bluemap.core.util.Keyed;
+import de.bluecolored.bluemap.core.util.Registry;
+import de.bluecolored.bluemap.core.world.BlockState;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+public interface EntityRendererType extends Keyed, EntityRendererFactory {
+
+ EntityRendererType DEFAULT = new Impl(Key.bluemap("default"), ResourceModelRenderer::new);
+ EntityRendererType MISSING = new Impl(Key.bluemap("missing"), MissingModelRenderer::new);
+
+ Registry REGISTRY = new Registry<>(
+ DEFAULT,
+ MISSING
+ );
+
+ /**
+ * If the loaded resourcepack does not have any resources for this entity, this method will be called.
+ * If this method returns true, this renderer will be used to render the entity instead.
+ *
+ *
+ * This can (and should only then) be used to provide a way of rendering entities that are completely dynamically
+ * created by a mod, and there is no way to provide static entity resources that point at the correct renderer.
+ *
+ *
+ * @param entityType The entity-type {@link Key} that was not found in the loaded resources.
+ * @return true if this renderer-type can render the provided entity-type {@link Key} despite missing resources.
+ */
+ default boolean isFallbackFor(Key entityType) {
+ return false;
+ }
+
+ @RequiredArgsConstructor
+ class Impl implements EntityRendererType {
+
+ @Getter private final Key key;
+ private final EntityRendererFactory rendererFactory;
+
+ @Override
+ public EntityRenderer create(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) {
+ return rendererFactory.create(resourcePack, textureGallery, renderSettings);
+ }
+
+ }
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/MissingModelRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/MissingModelRenderer.java
new file mode 100644
index 000000000..c7b64ff5c
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/MissingModelRenderer.java
@@ -0,0 +1,64 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.map.hires.entity;
+
+import com.github.benmanes.caffeine.cache.Caffeine;
+import com.github.benmanes.caffeine.cache.LoadingCache;
+import de.bluecolored.bluemap.core.logger.Logger;
+import de.bluecolored.bluemap.core.map.TextureGallery;
+import de.bluecolored.bluemap.core.map.hires.RenderSettings;
+import de.bluecolored.bluemap.core.map.hires.TileModelView;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.entitystate.Part;
+import de.bluecolored.bluemap.core.util.Key;
+import de.bluecolored.bluemap.core.world.Entity;
+import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
+
+public class MissingModelRenderer implements EntityRenderer {
+
+ private static final LoadingCache ENTITY_RENDERER_TYPES = Caffeine.newBuilder()
+ .maximumSize(1000)
+ .build(entityType -> {
+ for (EntityRendererType type : EntityRendererType.REGISTRY.values())
+ if (type.isFallbackFor(entityType)) return type;
+
+ Logger.global.logDebug("No renderer found for entity type: " + entityType);
+ return EntityRendererType.DEFAULT;
+ });
+
+ private final LoadingCache entityRenderers;
+
+ public MissingModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) {
+ this.entityRenderers = Caffeine.newBuilder()
+ .build(type -> type.create(resourcePack, textureGallery, renderSettings));
+ }
+
+ @Override
+ public void render(Entity entity, BlockNeighborhood block, Part part, TileModelView tileModel) {
+ entityRenderers.get(ENTITY_RENDERER_TYPES.get(entity.getId()))
+ .render(entity, block, part, tileModel);
+ }
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/ResourceModelRenderer.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/ResourceModelRenderer.java
new file mode 100644
index 000000000..238a7203f
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/entity/ResourceModelRenderer.java
@@ -0,0 +1,257 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.map.hires.entity;
+
+import com.flowpowered.math.vector.Vector3f;
+import com.flowpowered.math.vector.Vector4f;
+import de.bluecolored.bluemap.core.map.TextureGallery;
+import de.bluecolored.bluemap.core.map.hires.RenderSettings;
+import de.bluecolored.bluemap.core.map.hires.TileModel;
+import de.bluecolored.bluemap.core.map.hires.TileModelView;
+import de.bluecolored.bluemap.core.resources.ResourcePath;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.entitystate.Part;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Element;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Face;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Model;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.texture.Texture;
+import de.bluecolored.bluemap.core.util.Direction;
+import de.bluecolored.bluemap.core.util.math.Color;
+import de.bluecolored.bluemap.core.util.math.MatrixM4f;
+import de.bluecolored.bluemap.core.util.math.VectorM2f;
+import de.bluecolored.bluemap.core.util.math.VectorM3f;
+import de.bluecolored.bluemap.core.world.Entity;
+import de.bluecolored.bluemap.core.world.LightData;
+import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
+
+/**
+ * This model builder creates a BlockStateModel using the information from parsed resource-pack json files.
+ */
+@SuppressWarnings("DuplicatedCode")
+public class ResourceModelRenderer implements EntityRenderer {
+ private static final float SCALE = 1f / 16f;
+
+ final ResourcePack resourcePack;
+ final TextureGallery textureGallery;
+ final RenderSettings renderSettings;
+
+ private final VectorM3f[] corners = new VectorM3f[8];
+ private final VectorM2f[] rawUvs = new VectorM2f[4];
+ private final VectorM2f[] uvs = new VectorM2f[4];
+ private final Color tintColor = new Color();
+
+ private Model modelResource;
+ private TileModelView tileModel;
+ private int sunLight, blockLight;
+ private TintColorProvider tintProvider;
+
+ @SuppressWarnings("unused")
+ public ResourceModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) {
+ this.resourcePack = resourcePack;
+ this.textureGallery = textureGallery;
+ this.renderSettings = renderSettings;
+
+ for (int i = 0; i < corners.length; i++) corners[i] = new VectorM3f(0, 0, 0);
+ for (int i = 0; i < rawUvs.length; i++) rawUvs[i] = new VectorM2f(0, 0);
+ }
+
+ @Override
+ public void render(Entity entity, BlockNeighborhood block, Part part, TileModelView tileModel) {
+ render(
+ entity,
+ block,
+ part.getModel().getResource(resourcePack::getModel),
+ TintColorProvider.NO_TINT,
+ tileModel
+ );
+
+ // apply transform
+ if (part.isTransformed())
+ tileModel.transform(part.getTransformMatrix());
+ }
+
+ void render(Entity entity, BlockNeighborhood block, Model model, TintColorProvider tintProvider, TileModelView tileModel) {
+ this.modelResource = model;
+ this.tileModel = tileModel;
+ this.tintProvider = tintProvider;
+
+ // light calculation
+ LightData blockLightData = block.getLightData();
+ this.sunLight = blockLightData.getSkyLight();
+ this.blockLight = blockLightData.getBlockLight();
+
+ // filter out entities that are in a "cave" that should not be rendered
+ if (
+ block.isRemoveIfCave() &&
+ (renderSettings.isCaveDetectionUsesBlockLight() ? Math.max(blockLight, sunLight) : sunLight) == 0
+ ) return;
+
+ // render model
+ int modelStart = this.tileModel.getStart();
+
+ Element[] elements = modelResource.getElements();
+ if (elements != null) {
+ for (Element element : elements) {
+ buildModelElementResource(element, this.tileModel.initialize());
+ }
+ }
+
+ this.tileModel.initialize(modelStart);
+
+ }
+
+ private final MatrixM4f modelElementTransform = new MatrixM4f();
+ private void buildModelElementResource(Element element, TileModelView blockModel) {
+
+ //create faces
+ Vector3f from = element.getFrom();
+ Vector3f to = element.getTo();
+
+ float
+ minX = Math.min(from.getX(), to.getX()),
+ minY = Math.min(from.getY(), to.getY()),
+ minZ = Math.min(from.getZ(), to.getZ()),
+ maxX = Math.max(from.getX(), to.getX()),
+ maxY = Math.max(from.getY(), to.getY()),
+ maxZ = Math.max(from.getZ(), to.getZ());
+
+ VectorM3f[] c = corners;
+ c[0].x = minX; c[0].y = minY; c[0].z = minZ;
+ c[1].x = minX; c[1].y = minY; c[1].z = maxZ;
+ c[2].x = maxX; c[2].y = minY; c[2].z = minZ;
+ c[3].x = maxX; c[3].y = minY; c[3].z = maxZ;
+ c[4].x = minX; c[4].y = maxY; c[4].z = minZ;
+ c[5].x = minX; c[5].y = maxY; c[5].z = maxZ;
+ c[6].x = maxX; c[6].y = maxY; c[6].z = minZ;
+ c[7].x = maxX; c[7].y = maxY; c[7].z = maxZ;
+
+ int modelStart = blockModel.getStart();
+ createElementFace(element, Direction.DOWN, c[0], c[2], c[3], c[1]);
+ createElementFace(element, Direction.UP, c[5], c[7], c[6], c[4]);
+ createElementFace(element, Direction.NORTH, c[2], c[0], c[4], c[6]);
+ createElementFace(element, Direction.SOUTH, c[1], c[3], c[7], c[5]);
+ createElementFace(element, Direction.WEST, c[0], c[1], c[5], c[4]);
+ createElementFace(element, Direction.EAST, c[3], c[2], c[6], c[7]);
+ blockModel.initialize(modelStart);
+
+ //rotate and scale down
+ blockModel.transform(modelElementTransform
+ .copy(element.getRotation().getMatrix())
+ .scale(SCALE, SCALE, SCALE)
+ );
+ }
+
+ private void createElementFace(Element element, Direction faceDir, VectorM3f c0, VectorM3f c1, VectorM3f c2, VectorM3f c3) {
+ Face face = element.getFaces().get(faceDir);
+ if (face == null) return;
+
+ // initialize the faces
+ tileModel.initialize();
+ tileModel.add(2);
+
+ TileModel tileModel = this.tileModel.getTileModel();
+ int face1 = this.tileModel.getStart();
+ int face2 = face1 + 1;
+
+ // ####### positions
+ tileModel.setPositions(face1,
+ c0.x, c0.y, c0.z,
+ c1.x, c1.y, c1.z,
+ c2.x, c2.y, c2.z
+ );
+ tileModel.setPositions(face2,
+ c0.x, c0.y, c0.z,
+ c2.x, c2.y, c2.z,
+ c3.x, c3.y, c3.z
+ );
+
+ // ####### texture
+ ResourcePath texturePath = face.getTexture().getTexturePath(modelResource.getTextures()::get);
+ int textureId = textureGallery.get(texturePath);
+ tileModel.setMaterialIndex(face1, textureId);
+ tileModel.setMaterialIndex(face2, textureId);
+
+ // ####### UV
+ Vector4f uvRaw = face.getUv();
+ float
+ uvx = uvRaw.getX() / 16f,
+ uvy = uvRaw.getY() / 16f,
+ uvz = uvRaw.getZ() / 16f,
+ uvw = uvRaw.getW() / 16f;
+
+ rawUvs[0].set(uvx, uvw);
+ rawUvs[1].set(uvz, uvw);
+ rawUvs[2].set(uvz, uvy);
+ rawUvs[3].set(uvx, uvy);
+
+ // face-rotation
+ int rotationSteps = Math.floorDiv(face.getRotation(), 90) % 4;
+ if (rotationSteps < 0) rotationSteps += 4;
+ for (int i = 0; i < 4; i++)
+ uvs[i] = rawUvs[(rotationSteps + i) % 4];
+
+ tileModel.setUvs(face1,
+ uvs[0].x, uvs[0].y,
+ uvs[1].x, uvs[1].y,
+ uvs[2].x, uvs[2].y
+ );
+
+ tileModel.setUvs(face2,
+ uvs[0].x, uvs[0].y,
+ uvs[2].x, uvs[2].y,
+ uvs[3].x, uvs[3].y
+ );
+
+ // ####### face-tint
+ if (face.getTintindex() >= 0) {
+ tintProvider.setTintColor(face.getTintindex(), tintColor);
+ tileModel.setColor(face1, tintColor.r, tintColor.g, tintColor.b);
+ tileModel.setColor(face2, tintColor.r, tintColor.g, tintColor.b);
+ } else {
+ tileModel.setColor(face1, 1f, 1f, 1f);
+ tileModel.setColor(face2, 1f, 1f, 1f);
+ }
+
+ // ####### blocklight
+ int emissiveBlockLight = Math.max(blockLight, element.getLightEmission());
+ tileModel.setBlocklight(face1, emissiveBlockLight);
+ tileModel.setBlocklight(face2, emissiveBlockLight);
+
+ // ####### sunlight
+ tileModel.setSunlight(face1, sunLight);
+ tileModel.setSunlight(face2, sunLight);
+
+ // ######## AO
+ tileModel.setAOs(face1, 1f, 1f, 1f);
+ tileModel.setAOs(face2, 1f, 1f, 1f);
+
+ }
+
+ interface TintColorProvider {
+ TintColorProvider NO_TINT = (index, color) -> color.set(1f, 1f, 1f, 1f, true);
+ void setTintColor(int tintIndex, Color target);
+ }
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/BlockColorCalculatorFactory.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/BlockColorCalculatorFactory.java
index 41282d944..15e7a172a 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/BlockColorCalculatorFactory.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/BlockColorCalculatorFactory.java
@@ -28,7 +28,7 @@
import com.google.gson.stream.JsonReader;
import de.bluecolored.bluemap.core.util.math.Color;
import de.bluecolored.bluemap.core.world.biome.Biome;
-import de.bluecolored.bluemap.core.world.block.Block;
+import de.bluecolored.bluemap.core.world.block.BlockAccess;
import de.bluecolored.bluemap.core.world.block.BlockNeighborhood;
import java.awt.image.BufferedImage;
@@ -114,7 +114,7 @@ public BlockColorCalculator createCalculator() {
@FunctionalInterface
private interface ColorFunction {
- Color invoke(BlockColorCalculator calculator, BlockNeighborhood> block, Color target);
+ Color invoke(BlockColorCalculator calculator, BlockNeighborhood block, Color target);
}
public class BlockColorCalculator {
@@ -122,7 +122,7 @@ public class BlockColorCalculator {
private final Color tempColor = new Color();
@SuppressWarnings("UnusedReturnValue")
- public Color getBlockColor(BlockNeighborhood> block, Color target) {
+ public Color getBlockColor(BlockNeighborhood block, Color target) {
String blockId = block.getBlockState().getFormatted();
ColorFunction colorFunction = blockColorMap.get(blockId);
@@ -132,7 +132,7 @@ public Color getBlockColor(BlockNeighborhood> block, Color target) {
return colorFunction.invoke(this, block, target);
}
- public Color getRedstoneColor(Block> block, Color target) {
+ public Color getRedstoneColor(BlockAccess block, Color target) {
int power = block.getBlockState().getRedstonePower();
return target.set(
(power + 5f) / 20f, 0f, 0f,
@@ -140,7 +140,7 @@ public Color getRedstoneColor(Block> block, Color target) {
);
}
- public Color getBlendedWaterColor(BlockNeighborhood> block, Color target) {
+ public Color getBlendedWaterColor(BlockNeighborhood block, Color target) {
target.set(0, 0, 0, 0, true);
int x, y, z;
@@ -158,7 +158,7 @@ public Color getBlendedWaterColor(BlockNeighborhood> block, Color target) {
return target.flatten();
}
- public Color getBlendedFoliageColor(BlockNeighborhood> block, Color target) {
+ public Color getBlendedFoliageColor(BlockNeighborhood block, Color target) {
target.set(0, 0, 0, 0, true);
int x, y, z;
@@ -181,7 +181,7 @@ public Color getFoliageColor(Biome biome, Color target) {
return target.overlay(biome.getOverlayFoliageColor());
}
- public Color getBlendedGrassColor(BlockNeighborhood> block, Color target) {
+ public Color getBlendedGrassColor(BlockNeighborhood block, Color target) {
target.set(0, 0, 0, 0, true);
int x, y, z;
@@ -197,7 +197,7 @@ public Color getBlendedGrassColor(BlockNeighborhood> block, Color target) {
return target.flatten();
}
- public Color getGrassColor(Block> block, Color target) {
+ public Color getGrassColor(BlockAccess block, Color target) {
Biome biome = block.getBiome();
getColorFromMap(biome, grassMap, 0xff52952f, target);
target.overlay(biome.getOverlayGrassColor());
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/adapter/ResourcesGson.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/adapter/ResourcesGson.java
index e22c29db3..a62596bfd 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/adapter/ResourcesGson.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/adapter/ResourcesGson.java
@@ -29,8 +29,9 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
-import de.bluecolored.bluemap.core.map.hires.blockmodel.BlockRendererType;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.Face;
+import de.bluecolored.bluemap.core.map.hires.block.BlockRendererType;
+import de.bluecolored.bluemap.core.map.hires.entity.EntityRendererType;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Face;
import de.bluecolored.bluemap.core.util.Direction;
import de.bluecolored.bluemap.core.util.Key;
import de.bluecolored.bluemap.core.util.math.Axis;
@@ -70,6 +71,11 @@ public static GsonBuilder addAdapter(GsonBuilder builder) {
BlockRendererType.REGISTRY,
Key.BLUEMAP_NAMESPACE,
BlockRendererType.DEFAULT
+ ))
+ .registerTypeAdapter(EntityRendererType.class, new RegistryAdapter<>(
+ EntityRendererType.REGISTRY,
+ Key.BLUEMAP_NAMESPACE,
+ EntityRendererType.DEFAULT
));
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/ResourcePack.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/ResourcePack.java
index 700f0c9c8..e3481161a 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/ResourcePack.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/ResourcePack.java
@@ -33,11 +33,13 @@
import de.bluecolored.bluemap.core.resources.ResourcePath;
import de.bluecolored.bluemap.core.resources.adapter.ResourcesGson;
import de.bluecolored.bluemap.core.resources.pack.Pack;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.BlockModel;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.TextureVariable;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockstate.BlockState;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.entitystate.EntityState;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Model;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.TextureVariable;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.texture.AnimationMeta;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.texture.Texture;
+import de.bluecolored.bluemap.core.util.Key;
import de.bluecolored.bluemap.core.util.Tristate;
import de.bluecolored.bluemap.core.world.BlockProperties;
import org.jetbrains.annotations.Nullable;
@@ -59,11 +61,14 @@
public class ResourcePack extends Pack {
public static final ResourcePath MISSING_BLOCK_STATE = new ResourcePath<>("bluemap", "missing");
- public static final ResourcePath MISSING_BLOCK_MODEL = new ResourcePath<>("bluemap", "block/missing");
+ public static final ResourcePath MISSING_ENTITY_STATE = new ResourcePath<>("bluemap", "missing");
+ public static final ResourcePath MISSING_BLOCK_MODEL = new ResourcePath<>("bluemap", "block/missing");
+ public static final ResourcePath MISSING_ENTITY_MODEL = new ResourcePath<>("bluemap", "entity/missing");
public static final ResourcePath MISSING_TEXTURE = new ResourcePath<>("bluemap", "block/missing");
private final Map, BlockState> blockStates;
- private final Map, BlockModel> blockModels;
+ private final Map, EntityState> entityStates;
+ private final Map, Model> models;
private final Map, Texture> textures;
private final Map, BufferedImage> colormaps;
@@ -73,19 +78,19 @@ public class ResourcePack extends Pack {
private final Map, ResourcePackExtension> resourcePackExtensions;
private final Map> blockStatePaths;
+ private final Map> entityStatePaths;
private final Map> texturePaths;
private final LoadingCache blockPropertiesCache;
public ResourcePack(int packVersion) {
super(packVersion);
- this.blockStatePaths = new HashMap<>();
this.blockStates = new HashMap<>();
- this.blockModels = new HashMap<>();
- this.texturePaths = new HashMap<>();
+ this.entityStates = new HashMap<>();
+ this.models = new HashMap<>();
this.textures = new HashMap<>();
- this.colormaps = new HashMap<>();
+ this.colormaps = new HashMap<>();
this.colorCalculatorFactory = new BlockColorCalculatorFactory();
this.blockPropertiesConfig = new BlockPropertiesConfig();
@@ -93,6 +98,9 @@ public ResourcePack(int packVersion) {
for (ResourcePackExtensionType> extensionType : ResourcePackExtensionType.REGISTRY.values())
resourcePackExtensions.put(extensionType, extensionType.create());
+ this.blockStatePaths = new HashMap<>();
+ this.entityStatePaths = new HashMap<>();
+ this.texturePaths = new HashMap<>();
this.blockPropertiesCache = Caffeine.newBuilder()
.executor(BlueMap.THREAD_POOL)
.maximumSize(10000)
@@ -145,7 +153,22 @@ private void loadResources(Path root) throws IOException {
}, blockStates));
}, BlueMap.THREAD_POOL),
- // load blockmodels
+ // load entitystates
+ CompletableFuture.runAsync(() -> {
+ list(root.resolve("assets"))
+ .map(path -> path.resolve("entitystates"))
+ .filter(Files::isDirectory)
+ .flatMap(ResourcePack::walk)
+ .filter(path -> path.getFileName().toString().endsWith(".json"))
+ .filter(Files::isRegularFile)
+ .forEach(file -> loadResource(root, file, 1, 3, key -> {
+ try (BufferedReader reader = Files.newBufferedReader(file)) {
+ return ResourcesGson.INSTANCE.fromJson(reader, EntityState.class);
+ }
+ }, entityStates));
+ }, BlueMap.THREAD_POOL),
+
+ // load models
CompletableFuture.runAsync(() -> {
list(root.resolve("assets"))
.map(path -> path.resolve("models"))
@@ -156,9 +179,9 @@ private void loadResources(Path root) throws IOException {
.filter(Files::isRegularFile)
.forEach(file -> loadResource(root, file, 1, 3, key -> {
try (BufferedReader reader = Files.newBufferedReader(file)) {
- return ResourcesGson.INSTANCE.fromJson(reader, BlockModel.class);
+ return ResourcesGson.INSTANCE.fromJson(reader, Model.class);
}
- }, blockModels));
+ }, models));
}, BlueMap.THREAD_POOL),
// load colormaps
@@ -223,7 +246,7 @@ private void loadTextures(Path root) throws IOException {
// collect all used textures
Set> usedTextures = new HashSet<>();
usedTextures.add(MISSING_TEXTURE);
- for (BlockModel model : blockModels.values()) {
+ for (Model model : models.values()) {
for (TextureVariable textureVariable : model.getTextures().values()) {
if (textureVariable.isReference()) continue;
usedTextures.add(textureVariable.getTexturePath());
@@ -276,24 +299,25 @@ private void bake() throws IOException, InterruptedException {
// fill path maps
blockStates.keySet().forEach(path -> blockStatePaths.put(path.getFormatted(), path));
+ entityStates.keySet().forEach(path -> entityStatePaths.put(path, path));
textures.keySet().forEach(path -> texturePaths.put(path.getFormatted(), path));
// optimize references
- for (BlockModel model : blockModels.values()) {
+ for (Model model : models.values()) {
model.optimize(this);
}
if (Thread.interrupted()) throw new InterruptedException();
// apply model parents
- for (BlockModel model : blockModels.values()) {
+ for (Model model : models.values()) {
model.applyParent(this);
}
if (Thread.interrupted()) throw new InterruptedException();
// calculate model properties
- for (BlockModel model : blockModels.values()) {
+ for (Model model : models.values()) {
model.calculateProperties(this);
}
@@ -322,9 +346,19 @@ private void bake() throws IOException, InterruptedException {
return blockState != null ? blockState : MISSING_BLOCK_STATE.getResource(blockStates::get);
}
- public @Nullable BlockModel getBlockModel(ResourcePath path) {
- BlockModel blockModel = blockModels.get(path);
- return blockModel != null ? blockModel : MISSING_BLOCK_MODEL.getResource(blockModels::get);
+ public @Nullable EntityState getEntityState(Key entityId) {
+ ResourcePath path = entityStatePaths.get(entityId);
+ return path != null ? path.getResource(this::getEntityState) : MISSING_ENTITY_STATE.getResource(this::getEntityState);
+ }
+
+ public @Nullable EntityState getEntityState(ResourcePath path) {
+ EntityState entityState = entityStates.get(path);
+ return entityState != null ? entityState : MISSING_ENTITY_STATE.getResource(entityStates::get);
+ }
+
+ public @Nullable Model getModel(ResourcePath path) {
+ Model model = models.get(path);
+ return model != null ? model : MISSING_BLOCK_MODEL.getResource(models::get);
}
public @Nullable ResourcePath getTexturePath(String formatted) {
@@ -355,7 +389,7 @@ private BlockProperties loadBlockProperties(de.bluecolored.bluemap.core.world.Bl
BlockState resource = getBlockState(state);
if (resource != null) {
resource.forEach(state,0, 0, 0, variant -> {
- BlockModel model = variant.getModel().getResource(this::getBlockModel);
+ Model model = variant.getModel().getResource(this::getModel);
if (model != null) {
if (props.isOccluding() == Tristate.UNDEFINED) props.occluding(model.isOccluding());
if (props.isCulling() == Tristate.UNDEFINED) props.culling(model.isCulling());
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockstate/Variant.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockstate/Variant.java
index aefb0bf88..12a91d385 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockstate/Variant.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockstate/Variant.java
@@ -28,59 +28,39 @@
import com.google.gson.annotations.JsonAdapter;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
+import de.bluecolored.bluemap.core.map.hires.block.BlockRendererType;
import de.bluecolored.bluemap.core.resources.AbstractTypeAdapterFactory;
import de.bluecolored.bluemap.core.resources.ResourcePath;
-import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.BlockModel;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Model;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.util.math.MatrixM3f;
+import de.bluecolored.bluemap.core.util.math.MatrixM4f;
+import lombok.Getter;
import java.io.IOException;
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
@JsonAdapter(Variant.Adapter.class)
+@Getter
public class Variant {
- private ResourcePath model = ResourcePack.MISSING_BLOCK_MODEL;
+ private BlockRendererType renderer = BlockRendererType.DEFAULT;
+ private ResourcePath model = ResourcePack.MISSING_BLOCK_MODEL;
private float x = 0, y = 0;
private boolean uvlock = false;
private double weight = 1;
- private transient boolean rotated;
- private transient MatrixM3f rotationMatrix;
+ private transient boolean transformed;
+ private transient MatrixM4f transformMatrix;
private Variant(){}
private void init() {
- this.rotated = x != 0 || y != 0;
- this.rotationMatrix = new MatrixM3f().rotate(-x, -y, 0);
- }
-
- public ResourcePath getModel() {
- return model;
- }
-
- public float getX() {
- return x;
- }
-
- public float getY() {
- return y;
- }
-
- public boolean isUvlock() {
- return uvlock;
- }
-
- public double getWeight() {
- return weight;
- }
-
- public boolean isRotated() {
- return rotated;
- }
-
- public MatrixM3f getRotationMatrix() {
- return rotationMatrix;
+ this.transformed = x != 0 || y != 0;
+ this.transformMatrix = new MatrixM4f()
+ .translate(-0.5f, -0.5f, -0.5f)
+ .rotate(-x, -y, 0)
+ .translate(0.5f, 0.5f, 0.5f);
}
static class Adapter extends AbstractTypeAdapterFactory {
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/BlockEntityLoader.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/entitystate/EntityState.java
similarity index 86%
rename from core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/BlockEntityLoader.java
rename to core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/entitystate/EntityState.java
index bf76ab4fe..ac39df8b5 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/BlockEntityLoader.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/entitystate/EntityState.java
@@ -22,12 +22,14 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.world.block.entity;
+package de.bluecolored.bluemap.core.resources.pack.resourcepack.entitystate;
-import java.util.Map;
+import lombok.Getter;
-public interface BlockEntityLoader {
+@SuppressWarnings("FieldMayBeFinal")
+@Getter
+public class EntityState {
- BlockEntity load(Map raw);
+ private Part[] parts;
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/entitystate/Part.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/entitystate/Part.java
new file mode 100644
index 000000000..4d4bb519a
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/entitystate/Part.java
@@ -0,0 +1,79 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.resources.pack.resourcepack.entitystate;
+
+import com.flowpowered.math.vector.Vector3f;
+import com.google.gson.Gson;
+import com.google.gson.annotations.JsonAdapter;
+import com.google.gson.reflect.TypeToken;
+import com.google.gson.stream.JsonReader;
+import de.bluecolored.bluemap.core.map.hires.entity.EntityRendererType;
+import de.bluecolored.bluemap.core.resources.AbstractTypeAdapterFactory;
+import de.bluecolored.bluemap.core.resources.ResourcePath;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
+import de.bluecolored.bluemap.core.resources.pack.resourcepack.model.Model;
+import de.bluecolored.bluemap.core.util.math.MatrixM4f;
+import lombok.Getter;
+
+import java.io.IOException;
+
+@SuppressWarnings("FieldMayBeFinal")
+@JsonAdapter(Part.Adapter.class)
+@Getter
+public class Part {
+
+ private EntityRendererType renderer = EntityRendererType.DEFAULT;
+ private ResourcePath model = ResourcePack.MISSING_ENTITY_MODEL;
+ private Vector3f position = Vector3f.ZERO;
+ private Vector3f rotation = Vector3f.ZERO;
+
+ private transient boolean transformed;
+ private transient MatrixM4f transformMatrix;
+
+ private Part(){}
+
+ private void init() {
+ this.transformed = !position.equals(Vector3f.ZERO) || !rotation.equals(Vector3f.ZERO);
+ this.transformMatrix = new MatrixM4f()
+ .rotate(rotation.getX(), rotation.getY(), rotation.getZ())
+ .translate(position.getX(), position.getY(), position.getZ());
+ }
+
+ static class Adapter extends AbstractTypeAdapterFactory {
+
+ public Adapter() {
+ super(Part.class);
+ }
+
+ @Override
+ public Part read(JsonReader in, Gson gson) throws IOException {
+ Part part = gson.getDelegateAdapter(this, TypeToken.get(Part.class)).read(in);
+ part.init();
+ return part;
+ }
+
+ }
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Element.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Element.java
similarity index 68%
rename from core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Element.java
rename to core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Element.java
index 38ce530bd..4e39b9511 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Element.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Element.java
@@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel;
+package de.bluecolored.bluemap.core.resources.pack.resourcepack.model;
import com.flowpowered.math.vector.Vector3f;
import com.flowpowered.math.vector.Vector4f;
@@ -33,12 +33,14 @@
import de.bluecolored.bluemap.core.resources.AbstractTypeAdapterFactory;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.util.Direction;
+import lombok.Getter;
import java.io.IOException;
import java.util.EnumMap;
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
@JsonAdapter(Element.Adapter.class)
+@Getter
public class Element {
private static final Vector3f FULL_BLOCK_MIN = Vector3f.ZERO;
private static final Vector3f FULL_BLOCK_MAX = new Vector3f(16, 16, 16);
@@ -67,79 +69,31 @@ private void init() {
}
private Vector4f calculateDefaultUV(Direction face) {
- switch (face){
-
- case DOWN :
- case UP :
- return new Vector4f(
- from.getX(), from.getZ(),
- to.getX(), to.getZ()
- );
-
- case NORTH :
- case SOUTH :
- return new Vector4f(
- from.getX(), from.getY(),
- to.getX(), to.getY()
- );
-
- case WEST :
- case EAST :
- return new Vector4f(
- from.getZ(), from.getY(),
- to.getZ(), to.getY()
- );
-
- default :
- return new Vector4f(
- 0, 0,
- 16, 16
- );
-
- }
+ return switch (face) {
+ case DOWN, UP -> new Vector4f(
+ from.getX(), from.getZ(),
+ to.getX(), to.getZ()
+ );
+ case NORTH, SOUTH -> new Vector4f(
+ from.getX(), from.getY(),
+ to.getX(), to.getY()
+ );
+ case WEST, EAST -> new Vector4f(
+ from.getZ(), from.getY(),
+ to.getZ(), to.getY()
+ );
+ };
}
private Direction calculateDefaultCullface(Direction face) {
- switch (face) {
- case DOWN:
- return from.getY() == 0f ? Direction.DOWN : null;
- case UP:
- return to.getY() == 1f ? Direction.UP : null;
- case NORTH:
- return from.getZ() == 0f ? Direction.NORTH : null;
- case SOUTH:
- return to.getZ() == 1f ? Direction.SOUTH : null;
- case EAST:
- return to.getX() == 1f ? Direction.EAST : null;
- case WEST:
- return from.getX() == 0f ? Direction.WEST : null;
- default:
- return null;
- }
- }
-
- public Vector3f getFrom() {
- return from;
- }
-
- public Vector3f getTo() {
- return to;
- }
-
- public Rotation getRotation() {
- return rotation;
- }
-
- public boolean isShade() {
- return shade;
- }
-
- public int getLightEmission() {
- return lightEmission;
- }
-
- public EnumMap getFaces() {
- return faces;
+ return switch (face) {
+ case DOWN -> from.getY() == 0f ? Direction.DOWN : null;
+ case UP -> to.getY() == 1f ? Direction.UP : null;
+ case NORTH -> from.getZ() == 0f ? Direction.NORTH : null;
+ case SOUTH -> to.getZ() == 1f ? Direction.SOUTH : null;
+ case EAST -> to.getX() == 1f ? Direction.EAST : null;
+ case WEST -> from.getX() == 0f ? Direction.WEST : null;
+ };
}
public Element copy() {
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Face.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Face.java
similarity index 88%
rename from core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Face.java
rename to core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Face.java
index 2b9c42a30..16505a3fc 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Face.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Face.java
@@ -22,15 +22,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel;
+package de.bluecolored.bluemap.core.resources.pack.resourcepack.model;
import com.flowpowered.math.vector.Vector4f;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.util.Direction;
+import lombok.Getter;
import java.util.function.Function;
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
+@Getter
public class Face {
private static final TextureVariable DEFAULT_TEXTURE = new TextureVariable(ResourcePack.MISSING_TEXTURE);
@@ -57,26 +59,6 @@ void init(Direction direction, Function defaultUvCalculator
if (uv == null) uv = defaultUvCalculator.apply(direction);
}
- public Vector4f getUv() {
- return uv;
- }
-
- public TextureVariable getTexture() {
- return texture;
- }
-
- public Direction getCullface() {
- return cullface;
- }
-
- public int getRotation() {
- return rotation;
- }
-
- public int getTintindex() {
- return tintindex;
- }
-
public Face copy() {
return new Face(this);
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/BlockModel.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Model.java
similarity index 81%
rename from core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/BlockModel.java
rename to core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Model.java
index c26a5b20f..18852aa9b 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/BlockModel.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Model.java
@@ -22,62 +22,31 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel;
+package de.bluecolored.bluemap.core.resources.pack.resourcepack.model;
-import de.bluecolored.bluemap.core.map.hires.blockmodel.BlockRendererType;
import de.bluecolored.bluemap.core.resources.ResourcePath;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.texture.Texture;
import de.bluecolored.bluemap.core.util.Direction;
+import lombok.Getter;
import org.jetbrains.annotations.Nullable;
import java.util.HashMap;
import java.util.Map;
@SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"})
-public class BlockModel {
+@Getter
+public class Model {
- private BlockRendererType renderer = BlockRendererType.DEFAULT;
-
- private ResourcePath parent;
+ private @Nullable ResourcePath parent;
private Map textures = new HashMap<>();
- private Element[] elements;
+ private Element @Nullable [] elements;
private boolean ambientocclusion = true;
private transient boolean culling = false;
private transient boolean occluding = false;
- private BlockModel(){}
-
- public BlockRendererType getRenderer() {
- return renderer;
- }
-
- @Nullable
- public ResourcePath getParent() {
- return parent;
- }
-
- public Map getTextures() {
- return textures;
- }
-
- @Nullable
- public Element[] getElements() {
- return elements;
- }
-
- public boolean isAmbientocclusion() {
- return ambientocclusion;
- }
-
- public boolean isCulling() {
- return culling;
- }
-
- public boolean isOccluding() {
- return occluding;
- }
+ private Model(){}
public synchronized void optimize(ResourcePack resourcePack) {
for (var variable : this.textures.values()) {
@@ -95,10 +64,10 @@ public synchronized void applyParent(ResourcePack resourcePack) {
if (this.parent == null) return;
// set parent to null early to avoid trying to resolve reference-loops
- ResourcePath parentPath = this.parent;
+ ResourcePath parentPath = this.parent;
this.parent = null;
- BlockModel parent = parentPath.getResource(resourcePack::getBlockModel);
+ Model parent = parentPath.getResource(resourcePack::getModel);
if (parent != null) {
parent.applyParent(resourcePack);
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Rotation.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Rotation.java
similarity index 90%
rename from core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Rotation.java
rename to core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Rotation.java
index 47f0af128..7209cee27 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/Rotation.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/Rotation.java
@@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel;
+package de.bluecolored.bluemap.core.resources.pack.resourcepack.model;
import com.flowpowered.math.TrigMath;
import com.flowpowered.math.vector.Vector3f;
@@ -34,19 +34,19 @@
import de.bluecolored.bluemap.core.resources.AbstractTypeAdapterFactory;
import de.bluecolored.bluemap.core.util.math.Axis;
import de.bluecolored.bluemap.core.util.math.MatrixM4f;
+import lombok.Getter;
import java.io.IOException;
@SuppressWarnings("FieldMayBeFinal")
@JsonAdapter(Rotation.Adapter.class)
+@Getter
public class Rotation {
private static final Vector3f DEFAULT_ORIGIN = new Vector3f(8, 8, 8);
private static final double FIT_TO_BLOCK_SCALE_MULTIPLIER = 2 - Math.sqrt(2);
public static final Rotation ZERO = new Rotation();
- static {
- ZERO.init();
- }
+ static { ZERO.init(); }
private Vector3f origin = DEFAULT_ORIGIN;
private Axis axis = Axis.Y;
@@ -83,26 +83,6 @@ private void init() {
}
}
- public Vector3f getOrigin() {
- return origin;
- }
-
- public Axis getAxis() {
- return axis;
- }
-
- public double getAngle() {
- return angle;
- }
-
- public boolean isRescale() {
- return rescale;
- }
-
- public MatrixM4f getMatrix() {
- return matrix;
- }
-
static class Adapter extends AbstractTypeAdapterFactory {
public Adapter() {
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/TextureVariable.java b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/TextureVariable.java
similarity index 91%
rename from core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/TextureVariable.java
rename to core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/TextureVariable.java
index 8d2e397ed..dbdaa392d 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/blockmodel/TextureVariable.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/resources/pack/resourcepack/model/TextureVariable.java
@@ -22,7 +22,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-package de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel;
+package de.bluecolored.bluemap.core.resources.pack.resourcepack.model;
import com.google.gson.TypeAdapter;
import com.google.gson.annotations.JsonAdapter;
@@ -31,6 +31,8 @@
import de.bluecolored.bluemap.core.resources.ResourcePath;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.texture.Texture;
+import lombok.Getter;
+import lombok.Setter;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
@@ -40,7 +42,10 @@
@JsonAdapter(TextureVariable.Adapter.class)
public class TextureVariable {
- private String referenceName;
+ @Getter @Setter
+ private @Nullable String referenceName;
+
+ @Getter @Setter
private ResourcePath texturePath;
private transient volatile boolean isReference, isResolving;
@@ -66,20 +71,6 @@ public TextureVariable(ResourcePath texturePath) {
this.isResolving = false;
}
- @Nullable
- public String getReferenceName() {
- return referenceName;
- }
-
- public void setReferenceName(String referenceName) {
- this.referenceName = referenceName;
- }
-
- @Nullable
- public ResourcePath getTexturePath() {
- return texturePath;
- }
-
@Nullable
public ResourcePath getTexturePath(Function supplier) {
if (this.isReference) return resolveTexturePath(supplier);
@@ -105,10 +96,6 @@ private ResourcePath resolveTexturePath(Function texturePath) {
- this.texturePath = texturePath;
- }
-
public boolean isReference() {
return isReference;
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/BlockEntity.java b/core/src/main/java/de/bluecolored/bluemap/core/world/BlockEntity.java
new file mode 100644
index 000000000..c81c18613
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/BlockEntity.java
@@ -0,0 +1,39 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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 de.bluecolored.bluemap.core.util.Key;
+
+public interface BlockEntity {
+
+ Key getId();
+
+ int getX();
+ int getY();
+ int getZ();
+
+ boolean isKeepPacked();
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/Chunk.java b/core/src/main/java/de/bluecolored/bluemap/core/world/Chunk.java
index 0228becf1..4dcdda671 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/Chunk.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/Chunk.java
@@ -25,7 +25,6 @@
package de.bluecolored.bluemap.core.world;
import de.bluecolored.bluemap.core.world.biome.Biome;
-import de.bluecolored.bluemap.core.world.block.entity.BlockEntity;
import org.jetbrains.annotations.Nullable;
import java.util.function.Consumer;
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/Entity.java b/core/src/main/java/de/bluecolored/bluemap/core/world/Entity.java
new file mode 100644
index 000000000..328d1c134
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/Entity.java
@@ -0,0 +1,49 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.Vector2f;
+import com.flowpowered.math.vector.Vector3d;
+import de.bluecolored.bluemap.core.util.Key;
+
+import java.util.UUID;
+
+public interface Entity {
+
+ Key getId();
+
+ UUID getUuid();
+
+ String getCustomName();
+
+ boolean isCustomNameVisible();
+
+ Vector3d getPos();
+
+ Vector3d getMotion();
+
+ Vector2f getRotation();
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/World.java b/core/src/main/java/de/bluecolored/bluemap/core/world/World.java
index bd495ef16..27382bca0 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/World.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/World.java
@@ -29,10 +29,12 @@
import de.bluecolored.bluemap.core.util.Grid;
import de.bluecolored.bluemap.core.util.Key;
import de.bluecolored.bluemap.core.util.WatchService;
+import de.bluecolored.bluemap.core.world.block.BlockAccess;
import java.io.IOException;
import java.nio.file.Path;
import java.util.Collection;
+import java.util.function.Consumer;
import java.util.function.Predicate;
/**
@@ -107,6 +109,8 @@ default void preloadRegionChunks(int x, int z) {
*/
void invalidateChunkCache(int x, int z);
+ void iterateEntities(int minX, int minZ, int maxX, int maxZ, Consumer entityConsumer);
+
/**
* Generates a unique world-id based on a world-folder and a dimension
*/
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/biome/ColorModifier.java b/core/src/main/java/de/bluecolored/bluemap/core/world/biome/ColorModifier.java
index d46a74509..37c545dd3 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/biome/ColorModifier.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/biome/ColorModifier.java
@@ -25,10 +25,10 @@
package de.bluecolored.bluemap.core.world.biome;
import de.bluecolored.bluemap.core.util.math.Color;
-import de.bluecolored.bluemap.core.world.block.Block;
+import de.bluecolored.bluemap.core.world.block.BlockAccess;
public interface ColorModifier {
- void apply(Block> block, Color color);
+ void apply(BlockAccess block, Color color);
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/biome/GrassColorModifier.java b/core/src/main/java/de/bluecolored/bluemap/core/world/biome/GrassColorModifier.java
index f94a2ceba..f4a5f5e26 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/biome/GrassColorModifier.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/biome/GrassColorModifier.java
@@ -28,17 +28,17 @@
import de.bluecolored.bluemap.core.util.Keyed;
import de.bluecolored.bluemap.core.util.Registry;
import de.bluecolored.bluemap.core.util.math.Color;
-import de.bluecolored.bluemap.core.world.block.Block;
+import de.bluecolored.bluemap.core.world.block.BlockAccess;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
public interface GrassColorModifier extends Keyed, ColorModifier {
- GrassColorModifier NONE = new Impl(Key.minecraft("none"), (Block> block, Color color) -> {});
- GrassColorModifier DARK_FOREST = new Impl(Key.minecraft("dark_forest"), (Block> block, Color color) ->
+ GrassColorModifier NONE = new Impl(Key.minecraft("none"), (BlockAccess block, Color color) -> {});
+ GrassColorModifier DARK_FOREST = new Impl(Key.minecraft("dark_forest"), (BlockAccess block, Color color) ->
color.set(((color.getInt() & 0xfefefe) + 0x28340a >> 1) | 0xff000000, true)
);
- GrassColorModifier SWAMP = new Impl(Key.minecraft("swamp"), (Block> block, Color color) -> {
+ GrassColorModifier SWAMP = new Impl(Key.minecraft("swamp"), (BlockAccess block, Color color) -> {
color.set(0xff6a7039, true);
/* Vanilla code with noise:
@@ -63,7 +63,7 @@ class Impl implements GrassColorModifier {
private final ColorModifier modifier;
@Override
- public void apply(Block> block, Color color) {
+ public void apply(BlockAccess block, Color color) {
modifier.apply(block, color);
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/block/Block.java b/core/src/main/java/de/bluecolored/bluemap/core/world/block/Block.java
index 7f5ec17cf..c5d3b7b9c 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/block/Block.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/block/Block.java
@@ -26,13 +26,13 @@
import de.bluecolored.bluemap.core.world.*;
import de.bluecolored.bluemap.core.world.biome.Biome;
-import de.bluecolored.bluemap.core.world.block.entity.BlockEntity;
+import lombok.Getter;
import org.jetbrains.annotations.Nullable;
-public class Block> {
+public class Block implements BlockAccess {
- private World world;
- private int x, y, z;
+ @Getter private final World world;
+ @Getter private int x, y, z;
private @Nullable Chunk chunk;
@@ -44,29 +44,14 @@ public class Block> {
private @Nullable BlockEntity blockEntity;
public Block(World world, int x, int y, int z) {
- set(world, x, y, z);
- }
-
- public T set(World world, int x, int y, int z) {
- if (this.x == x && this.z == z && this.world == world){
- if (this.y == y) return self();
- } else {
- this.chunk = null; //only reset the chunk if x or z have changed
- }
-
this.world = world;
- this.x = x;
- this.y = y;
- this.z = z;
-
- reset();
-
- return self();
+ set(x, y, z);
}
- public T set(int x, int y, int z) {
+ @Override
+ public void set(int x, int y, int z) {
if (this.x == x && this.z == z){
- if (this.y == y) return self();
+ if (this.y == y) return;
} else {
this.chunk = null; //only reset the chunk if x or z have changed
}
@@ -75,12 +60,6 @@ public T set(int x, int y, int z) {
this.y = y;
this.z = z;
- reset();
-
- return self();
- }
-
- protected void reset() {
this.blockState = null;
this.lightData.set(-1, -1);
this.biome = null;
@@ -88,40 +67,9 @@ protected void reset() {
this.blockEntity = null;
}
- public T add(int dx, int dy, int dz) {
- return set(x + dx, y + dy, z + dz);
- }
-
- public T copy(Block> source) {
- this.world = source.world;
- this.chunk = source.chunk;
- this.x = source.x;
- this.y = source.y;
- this.z = source.z;
-
- reset();
-
- this.blockState = source.blockState;
- this.lightData.set(source.lightData.getSkyLight(), source.lightData.getBlockLight());
- this.biome = source.biome;
-
- return self();
- }
-
- public World getWorld() {
- return world;
- }
-
- public int getX() {
- return x;
- }
-
- public int getY() {
- return y;
- }
-
- public int getZ() {
- return z;
+ @Override
+ public BlockAccess copy() {
+ return new Block(world, x, y, z);
}
public Chunk getChunk() {
@@ -129,29 +77,24 @@ public Chunk getChunk() {
return chunk;
}
+ @Override
public BlockState getBlockState() {
if (blockState == null) blockState = getChunk().getBlockState(x, y, z);
return blockState;
}
+ @Override
public LightData getLightData() {
if (lightData.getSkyLight() < 0) getChunk().getLightData(x, y, z, lightData);
return lightData;
}
+ @Override
public Biome getBiome() {
if (biome == null) biome = getChunk().getBiome(x, y, z);
return biome;
}
- public int getSunLightLevel() {
- return getLightData().getSkyLight();
- }
-
- public int getBlockLightLevel() {
- return getLightData().getBlockLight();
- }
-
public @Nullable BlockEntity getBlockEntity() {
if (!isBlockEntitySet) {
blockEntity = getChunk().getBlockEntity(x, y, z);
@@ -161,30 +104,13 @@ public int getBlockLightLevel() {
}
@Override
- public String toString() {
- if (world != null) {
- return "Block{" +
- "world=" + world +
- ", x=" + x +
- ", y=" + y +
- ", z=" + z +
- ", chunk=" + getChunk() +
- ", blockState=" + getBlockState() +
- ", lightData=" + getLightData() +
- ", biome=" + getBiome() +
- '}';
- } else {
- return "Block{" +
- "world=null" +
- ", x=" + x +
- ", y=" + y +
- ", z=" + z +
- '}';
- }
+ public boolean hasOceanFloorY() {
+ return getChunk().hasOceanFloorHeights();
}
- @SuppressWarnings("unchecked")
- protected T self() {
- return (T) this;
+ @Override
+ public int getOceanFloorY() {
+ return getChunk().getOceanFloorY(x, z);
}
+
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/block/BlockAccess.java b/core/src/main/java/de/bluecolored/bluemap/core/world/block/BlockAccess.java
new file mode 100644
index 000000000..c1217880b
--- /dev/null
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/block/BlockAccess.java
@@ -0,0 +1,61 @@
+/*
+ * This file is part of BlueMap, licensed under the MIT License (MIT).
+ *
+ * Copyright (c) Blue (Lukas Rieger)
+ * 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.block;
+
+import de.bluecolored.bluemap.core.world.BlockEntity;
+import de.bluecolored.bluemap.core.world.BlockState;
+import de.bluecolored.bluemap.core.world.LightData;
+import de.bluecolored.bluemap.core.world.biome.Biome;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Nullable;
+
+public interface BlockAccess {
+
+ void set(int x, int y, int z);
+
+ @Contract(" -> new")
+ BlockAccess copy();
+
+ int getX();
+ int getY();
+ int getZ();
+
+ BlockState getBlockState();
+ LightData getLightData();
+ Biome getBiome();
+ @Nullable BlockEntity getBlockEntity();
+
+ boolean hasOceanFloorY();
+ int getOceanFloorY();
+
+ default int getSunLightLevel() {
+ return getLightData().getSkyLight();
+ }
+
+ default int getBlockLightLevel() {
+ return getLightData().getBlockLight();
+ }
+
+}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/block/BlockNeighborhood.java b/core/src/main/java/de/bluecolored/bluemap/core/world/block/BlockNeighborhood.java
index 82d112d78..d1bff37ad 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/block/BlockNeighborhood.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/block/BlockNeighborhood.java
@@ -26,61 +26,36 @@
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
-import de.bluecolored.bluemap.core.world.World;
+import de.bluecolored.bluemap.core.world.DimensionType;
-public class BlockNeighborhood> extends ExtendedBlock {
+public class BlockNeighborhood extends ExtendedBlock {
- private static final int DIAMETER = 8;
+ private static final int DIAMETER = 8; // must be a power of 2
private static final int DIAMETER_MASK = DIAMETER - 1;
private static final int DIAMETER_SQUARED = DIAMETER * DIAMETER;
- private final ExtendedBlock>[] neighborhood;
+ private final ExtendedBlock[] neighborhood;
- private int thisIndex;
+ private int thisIndex = -1;
- public BlockNeighborhood(ExtendedBlock> center) {
- super(center.getResourcePack(), center.getRenderSettings(), null, 0, 0, 0);
- copy(center);
+ public BlockNeighborhood(BlockAccess blockAccess, ResourcePack resourcePack, RenderSettings renderSettings, DimensionType dimensionType) {
+ super(blockAccess, resourcePack, renderSettings, dimensionType);
- neighborhood = new ExtendedBlock[DIAMETER * DIAMETER * DIAMETER];
- init();
- }
-
- public BlockNeighborhood(ResourcePack resourcePack, RenderSettings renderSettings, World world, int x, int y, int z) {
- super(resourcePack, renderSettings, world, x, y, z);
-
- neighborhood = new ExtendedBlock[DIAMETER * DIAMETER * DIAMETER];
- init();
+ this.neighborhood = new ExtendedBlock[DIAMETER * DIAMETER * DIAMETER];
}
@Override
- public T set(int x, int y, int z) {
- return copy(getBlock(x, y, z));
- }
-
- @Override
- public T set(World world, int x, int y, int z) {
- if (getWorld() == world)
- return copy(getBlock(x, y, z));
- else
- return super.set(world, x, y, z);
- }
-
- @Override
- protected void reset() {
- super.reset();
-
- this.thisIndex = -1;
- }
+ public void set(int x, int y, int z) {
+ int i = index(x, y, z);
+ if (i == thisIndex()) return;
- private void init() {
- this.thisIndex = -1;
- for (int i = 0; i < neighborhood.length; i++) {
- neighborhood[i] = new ExtendedBlock<>(this.getResourcePack(), this.getRenderSettings(), null, 0, 0, 0);
- }
+ if (neighborhood[i] == null) neighborhood[i] = copy();
+ neighborhood[i].set(x, y, z);
+ copyFrom(neighborhood[i]);
+ this.thisIndex = i;
}
- public ExtendedBlock> getNeighborBlock(int dx, int dy, int dz) {
+ public ExtendedBlock getNeighborBlock(int dx, int dy, int dz) {
return getBlock(
getX() + dx,
getY() + dy,
@@ -88,10 +63,13 @@ public ExtendedBlock> getNeighborBlock(int dx, int dy, int dz) {
);
}
- private ExtendedBlock> getBlock(int x, int y, int z) {
+ private ExtendedBlock getBlock(int x, int y, int z) {
int i = index(x, y, z);
if (i == thisIndex()) return this;
- return neighborhood[i].set(getWorld(), x, y, z);
+
+ if (neighborhood[i] == null) neighborhood[i] = copy();
+ neighborhood[i].set(x, y, z);
+ return neighborhood[i];
}
private int thisIndex() {
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/block/ExtendedBlock.java b/core/src/main/java/de/bluecolored/bluemap/core/world/block/ExtendedBlock.java
index ca7cb94f0..eb08c495b 100644
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/block/ExtendedBlock.java
+++ b/core/src/main/java/de/bluecolored/bluemap/core/world/block/ExtendedBlock.java
@@ -27,71 +27,106 @@
import de.bluecolored.bluemap.core.map.hires.RenderSettings;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.world.*;
+import de.bluecolored.bluemap.core.world.biome.Biome;
+import lombok.Getter;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
-public class ExtendedBlock> extends Block {
- private final ResourcePack resourcePack;
- private final RenderSettings renderSettings;
+public class ExtendedBlock implements BlockAccess {
+
+ @Getter private int x, y, z;
+ private BlockAccess blockAccess;
+
+ @Getter private ResourcePack resourcePack;
+ @Getter private RenderSettings renderSettings;
+ @Getter private DimensionType dimensionType;
private @Nullable BlockProperties properties;
private boolean insideRenderBoundsCalculated, insideRenderBounds;
private boolean isCaveCalculated, isCave;
- public ExtendedBlock(ResourcePack resourcePack, RenderSettings renderSettings, World world, int x, int y, int z) {
- super(world, x, y, z);
+ public ExtendedBlock(BlockAccess blockAccess, ResourcePack resourcePack, RenderSettings renderSettings, DimensionType dimensionType) {
+ this.blockAccess = Objects.requireNonNull(blockAccess);
this.resourcePack = Objects.requireNonNull(resourcePack);
- this.renderSettings = renderSettings;
+ this.renderSettings = Objects.requireNonNull(renderSettings);
+ this.dimensionType = Objects.requireNonNull(dimensionType);
}
@Override
- protected void reset() {
- super.reset();
+ public void set(int x, int y, int z) {
+ if (this.y == y && this.x == x && this.z == z)
+ return;
- this.properties = null;
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.blockAccess.set(x, y, z);
+ this.properties = null;
this.insideRenderBoundsCalculated = false;
this.isCaveCalculated = false;
}
- public T copy(ExtendedBlock> source) {
- super.copy(source);
-
- this.properties = source.properties;
-
- this.insideRenderBoundsCalculated = source.insideRenderBoundsCalculated;
- this.insideRenderBounds = source.insideRenderBounds;
-
- this.isCaveCalculated = source.isCaveCalculated;
- this.isCave = source.isCave;
+ @Override
+ public ExtendedBlock copy() {
+ return new ExtendedBlock(blockAccess.copy(), resourcePack, renderSettings, dimensionType);
+ }
- return self();
+ protected void copyFrom(ExtendedBlock extendedBlock) {
+ this.x = extendedBlock.x;
+ this.y = extendedBlock.y;
+ this.z = extendedBlock.z;
+ this.blockAccess = extendedBlock.blockAccess;
+ this.resourcePack = extendedBlock.resourcePack;
+ this.renderSettings = extendedBlock.renderSettings;
+ this.dimensionType = extendedBlock.dimensionType;
+ this.properties = extendedBlock.properties;
+ this.insideRenderBoundsCalculated = extendedBlock.insideRenderBoundsCalculated;
+ this.insideRenderBounds = extendedBlock.insideRenderBounds;
+ this.isCaveCalculated = extendedBlock.isCaveCalculated;
+ this.isCave = extendedBlock.isCave;
}
@Override
public BlockState getBlockState() {
if (renderSettings.isRenderEdges() && !isInsideRenderBounds()) return BlockState.AIR;
- return super.getBlockState();
+ return blockAccess.getBlockState();
}
@Override
public LightData getLightData() {
- LightData ld = super.getLightData();
- if (renderSettings.isRenderEdges() && !isInsideRenderBounds()) ld.set(getWorld().getDimensionType().hasSkylight() ? 16 : 0, ld.getBlockLight());
+ LightData ld = blockAccess.getLightData();
+ if (renderSettings.isRenderEdges() && !isInsideRenderBounds()) ld.set(dimensionType.hasSkylight() ? 16 : 0, ld.getBlockLight());
return ld;
}
+ @Override
+ public Biome getBiome() {
+ return blockAccess.getBiome();
+ }
+
+ @Override
+ public @Nullable BlockEntity getBlockEntity() {
+ return blockAccess.getBlockEntity();
+ }
+
+ @Override
+ public boolean hasOceanFloorY() {
+ return blockAccess.hasOceanFloorY();
+ }
+
+ @Override
+ public int getOceanFloorY() {
+ return blockAccess.getOceanFloorY();
+ }
+
public BlockProperties getProperties() {
if (properties == null) properties = resourcePack.getBlockProperties(getBlockState());
return properties;
}
- public RenderSettings getRenderSettings() {
- return renderSettings;
- }
-
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean isInsideRenderBounds() {
if (!insideRenderBoundsCalculated) {
@@ -106,8 +141,8 @@ public boolean isRemoveIfCave() {
if (!isCaveCalculated) {
isCave = getY() < renderSettings.getRemoveCavesBelowY() &&
(
- !getChunk().hasOceanFloorHeights() ||
- getY() < getChunk().getOceanFloorY(getX(), getZ()) +
+ !hasOceanFloorY() ||
+ getY() < getOceanFloorY() +
renderSettings.getCaveDetectionOceanFloor()
);
isCaveCalculated = true;
@@ -116,8 +151,4 @@ public boolean isRemoveIfCave() {
return isCave;
}
- public ResourcePack getResourcePack() {
- return resourcePack;
- }
-
}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/BlockEntity.java b/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/BlockEntity.java
deleted file mode 100644
index 5b42e134b..000000000
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/BlockEntity.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * This file is part of BlueMap, licensed under the MIT License (MIT).
- *
- * Copyright (c) Blue (Lukas Rieger)
- * 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.block.entity;
-
-import de.bluecolored.bluemap.core.util.Key;
-import de.bluecolored.bluenbt.*;
-import lombok.EqualsAndHashCode;
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import lombok.ToString;
-import org.jetbrains.annotations.Nullable;
-
-import java.io.IOException;
-import java.util.Map;
-
-@Getter
-@EqualsAndHashCode
-@ToString
-@NBTDeserializer(BlockEntity.BlockEntityDeserializer.class)
-public abstract class BlockEntity {
-
- protected final String id;
- protected final int x, y, z;
- protected final boolean keepPacked;
-
- protected BlockEntity(Map raw) {
- this.id = (String) raw.get("id");
- this.x = (int) raw.getOrDefault("x", 0);
- this.y = (int) raw.getOrDefault("y", 0);
- this.z = (int) raw.getOrDefault("z", 0);
- this.keepPacked = (byte) raw.getOrDefault("keepPacked", (byte) 0) == 1;
- }
-
- @RequiredArgsConstructor
- public static class BlockEntityDeserializer implements TypeDeserializer {
-
- private final BlueNBT blueNBT;
-
- @Override
- @SuppressWarnings("unchecked")
- public @Nullable BlockEntity read(NBTReader reader) throws IOException {
- Map raw = (Map) blueNBT.read(reader, TypeToken.of(Map.class, String.class, Object.class));
-
- String id = (String) raw.get("id");
- if (id == null) return null;
-
- Key typeKey = Key.parse(id, Key.MINECRAFT_NAMESPACE);
- BlockEntityType type = BlockEntityType.REGISTRY.get(typeKey);
- if (type == null) return null;
-
- return type.load(raw);
- }
-
- }
-
-}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/SignBlockEntity.java b/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/SignBlockEntity.java
deleted file mode 100644
index 4327987e1..000000000
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/SignBlockEntity.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * This file is part of BlueMap, licensed under the MIT License (MIT).
- *
- * Copyright (c) Blue (Lukas Rieger)
- * 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.block.entity;
-
-import java.util.List;
-import java.util.Map;
-
-public class SignBlockEntity extends BlockEntity {
- private final TextData frontText;
- private final TextData backText;
-
- @SuppressWarnings("unchecked")
- protected SignBlockEntity(Map data) {
- super(data);
-
- // Versions before 1.20 used a different format
- if (data.containsKey("front_text")) {
- this.frontText = new TextData((Map) data.getOrDefault("front_text", Map.of()));
- this.backText = new TextData((Map) data.getOrDefault("back_text", Map.of()));
- } else {
- this.frontText = new TextData(
- (byte) data.getOrDefault("GlowingText", (byte) 0) == 1,
- (String) data.getOrDefault("Color", ""),
- List.of(
- (String) data.getOrDefault("Text1", ""),
- (String) data.getOrDefault("Text2", ""),
- (String) data.getOrDefault("Text3", ""),
- (String) data.getOrDefault("Text4", "")
- )
- );
-
- this.backText = new TextData(false, "", List.of());
- }
- }
-
- public TextData getFrontText() {
- return frontText;
- }
-
- public TextData getBackText() {
- return backText;
- }
-
- @Override
- public String toString() {
- return "SignBlockEntity{" +
- "frontText=" + frontText +
- ", backText=" + backText +
- "} " + super.toString();
- }
-
- public static class TextData {
- private final boolean hasGlowingText;
- private final String color;
- private final List messages;
-
- @SuppressWarnings("unchecked")
- private TextData(Map data) {
- this.hasGlowingText = (byte) data.getOrDefault("has_glowing_text", (byte) 0) == 1;
- this.color = (String) data.getOrDefault("color", "");
- this.messages = (List) data.getOrDefault("messages", List.of());
- }
-
- public TextData(boolean hasGlowingText, String color, List messages) {
- this.hasGlowingText = hasGlowingText;
- this.color = color;
- this.messages = messages;
- }
-
- public boolean isHasGlowingText() {
- return hasGlowingText;
- }
-
- public String getColor() {
- return color;
- }
-
- public List getMessages() {
- return messages;
- }
-
- @Override
- public String toString() {
- return "TextData{" +
- "hasGlowingText=" + hasGlowingText +
- ", color='" + color + '\'' +
- ", messages=" + messages +
- '}';
- }
- }
-}
diff --git a/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/SkullBlockEntity.java b/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/SkullBlockEntity.java
deleted file mode 100644
index daafb0a7b..000000000
--- a/core/src/main/java/de/bluecolored/bluemap/core/world/block/entity/SkullBlockEntity.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * This file is part of BlueMap, licensed under the MIT License (MIT).
- *
- * Copyright (c) Blue (Lukas Rieger)
- * 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.block.entity;
-
-import lombok.Getter;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.UUID;
-
-@Getter
-public class SkullBlockEntity extends BlockEntity {
- private final @Nullable String noteBlockSound;
- private final @Nullable String extraType;
- private final @Nullable SkullOwner skullOwner;
-
- protected SkullBlockEntity(Map data) {
- super(data);
-
- this.noteBlockSound = (String) data.get("note_block_sound");
- this.extraType = (String) data.get("ExtraType");
-
- @SuppressWarnings("unchecked")
- Map ownerData = (Map) data.get("SkullOwner");
- this.skullOwner = ownerData != null ? new SkullOwner(ownerData) : null;
- }
-
- @Override
- public String toString() {
- return "SkullBlockEntity{" +
- "noteBlockSound='" + noteBlockSound + '\'' +
- ", extraType='" + extraType + '\'' +
- ", skullOwner=" + skullOwner +
- "} " + super.toString();
- }
-
- @Getter
- public static class SkullOwner {
- private final @Nullable UUID id;
- private final @Nullable String name;
- private final List textures = new ArrayList<>();
-
- @SuppressWarnings("unchecked")
- private SkullOwner(Map data) {
- int @Nullable [] uuidInts = (int[]) data.get("Id");
-
- if (uuidInts == null || uuidInts.length != 4) {
- this.id = null;
- } else {
- this.id = new UUID((long) uuidInts[0] << 32 | uuidInts[1], (long) uuidInts[2] << 32 | uuidInts[3]);
- }
-
- this.name = (String) data.get("Name");
-
- Map properties = (Map) data.getOrDefault("Properties", Map.of());
- List