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 8f9de6e07..251098c19 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 @@ -27,7 +27,7 @@ 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.BlockStateModelFactory; +import de.bluecolored.bluemap.core.map.hires.blockmodel.BlockStateModelRenderer; import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack; import de.bluecolored.bluemap.core.util.math.Color; import de.bluecolored.bluemap.core.world.Chunk; @@ -39,31 +39,31 @@ public class HiresModelRenderer { private final ResourcePack resourcePack; private final RenderSettings renderSettings; - private final ThreadLocal threadLocalModelFactory; + private final ThreadLocal threadLocalBlockRenderer; public HiresModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) { this.resourcePack = resourcePack; this.renderSettings = renderSettings; - this.threadLocalModelFactory = ThreadLocal.withInitial(() -> new BlockStateModelFactory(resourcePack, textureGallery, renderSettings)); + this.threadLocalBlockRenderer = ThreadLocal.withInitial(() -> new BlockStateModelRenderer(resourcePack, textureGallery, renderSettings)); } public void render(World world, Vector3i modelMin, Vector3i modelMax, TileModel model) { render(world, modelMin, modelMax, model, (x, z, c, h, l) -> {}); } - public void render(World world, Vector3i modelMin, Vector3i modelMax, TileModel model, TileMetaConsumer tileMetaConsumer) { + public void render(World world, Vector3i modelMin, Vector3i modelMax, TileModel tileModel, TileMetaConsumer tileMetaConsumer) { Vector3i min = modelMin.max(renderSettings.getMinPos()); Vector3i max = modelMax.min(renderSettings.getMaxPos()); Vector3i modelAnchor = new Vector3i(modelMin.getX(), 0, modelMin.getZ()); - BlockStateModelFactory modelFactory = threadLocalModelFactory.get(); + BlockStateModelRenderer blockRenderer = threadLocalBlockRenderer.get(); int maxHeight, minY, maxY; double topBlockLight; Color columnColor = new Color(), blockColor = new Color(); BlockNeighborhood block = new BlockNeighborhood<>(resourcePack, renderSettings, world, 0, 0, 0); - BlockModelView blockModel = new BlockModelView(model); + TileModelView blockModel = new TileModelView(tileModel); int x, y, z; for (x = modelMin.getX(); x <= modelMax.getX(); x++){ @@ -85,7 +85,7 @@ public void render(World world, Vector3i modelMin, Vector3i modelMax, TileModel blockModel.initialize(); - modelFactory.render(block, blockModel, blockColor); + blockRenderer.render(block, blockModel, blockColor); //update topBlockLight topBlockLight = Math.max(topBlockLight, block.getBlockLightLevel() * (1 - columnColor.a)); diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/BlockModelView.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/TileModelView.java similarity index 65% rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/BlockModelView.java rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/TileModelView.java index 8fff9aaaa..72415c68c 100644 --- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/BlockModelView.java +++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/TileModelView.java @@ -27,90 +27,90 @@ import de.bluecolored.bluemap.core.util.math.MatrixM3f; import de.bluecolored.bluemap.core.util.math.MatrixM4f; -public class BlockModelView { +public class TileModelView { - private TileModel hiresTile; + private TileModel tileModel; private int start, size; - public BlockModelView(TileModel hiresTile) { - initialize(hiresTile); + public TileModelView(TileModel tileModel) { + initialize(tileModel); } - public BlockModelView initialize(TileModel hiresTile, int start) { - this.hiresTile = hiresTile; + public TileModelView initialize(TileModel hiresTile, int start) { + this.tileModel = hiresTile; this.start = start; this.size = hiresTile.size() - start; return this; } - public BlockModelView initialize(TileModel hiresTile) { - this.hiresTile = hiresTile; + public TileModelView initialize(TileModel hiresTile) { + this.tileModel = hiresTile; this.start = hiresTile.size(); this.size = 0; return this; } - public BlockModelView initialize(int start) { + public TileModelView initialize(int start) { this.start = start; - this.size = hiresTile.size() - start; + this.size = tileModel.size() - start; return this; } - public BlockModelView initialize() { - this.start = hiresTile.size(); + public TileModelView initialize() { + this.start = tileModel.size(); this.size = 0; return this; } - public BlockModelView reset() { - hiresTile.reset(this.start); + public TileModelView reset() { + tileModel.reset(this.start); this.size = 0; return this; } public int add(int count) { - int s = hiresTile.add(count); + int s = tileModel.add(count); if (s != start + size) throw new IllegalStateException("Size of HiresTileModel had external changes since view-initialisation!"); this.size += count; return s; } - public BlockModelView rotate(float angle, float axisX, float axisY, float axisZ) { - hiresTile.rotate(start, size, angle, axisX, axisY, axisZ); + public TileModelView rotate(float angle, float axisX, float axisY, float axisZ) { + tileModel.rotate(start, size, angle, axisX, axisY, axisZ); return this; } - public BlockModelView rotate(float pitch, float yaw, float roll) { - hiresTile.rotate(start, size, pitch, yaw, roll); + public TileModelView rotate(float pitch, float yaw, float roll) { + tileModel.rotate(start, size, pitch, yaw, roll); return this; } - public BlockModelView scale(float sx, float sy, float sz) { - hiresTile.scale(start, size, sx, sy, sz); + public TileModelView scale(float sx, float sy, float sz) { + tileModel.scale(start, size, sx, sy, sz); return this; } - public BlockModelView translate(float dx, float dy, float dz) { - hiresTile.translate(start, size, dx, dy, dz); + public TileModelView translate(float dx, float dy, float dz) { + tileModel.translate(start, size, dx, dy, dz); return this; } - public BlockModelView transform(MatrixM3f t) { - hiresTile.transform(start, size, t); + public TileModelView transform(MatrixM3f t) { + tileModel.transform(start, size, t); return this; } - public BlockModelView transform( + public TileModelView transform( float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22 ) { - hiresTile.transform(start, size, + tileModel.transform(start, size, m00, m01, m02, m10, m11, m12, m20, m21, m22 @@ -118,18 +118,18 @@ public BlockModelView transform( return this; } - public BlockModelView transform(MatrixM4f t) { - hiresTile.transform(start, size, t); + public TileModelView transform(MatrixM4f t) { + tileModel.transform(start, size, t); return this; } - public BlockModelView transform( + public TileModelView transform( float m00, float m01, float m02, float m03, float m10, float m11, float m12, float m13, float m20, float m21, float m22, float m23, float m30, float m31, float m32, float m33 ) { - hiresTile.transform(start, size, + tileModel.transform(start, size, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, @@ -138,8 +138,8 @@ public BlockModelView transform( return this; } - public TileModel getHiresTile() { - return hiresTile; + public TileModel getTileModel() { + return tileModel; } public int getStart() { 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/blockmodel/BlockRenderer.java new file mode 100644 index 000000000..8f4a2a303 --- /dev/null +++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRenderer.java @@ -0,0 +1,27 @@ +package de.bluecolored.bluemap.core.map.hires.blockmodel; + +import de.bluecolored.bluemap.core.map.hires.TileModelView; +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; + +public interface BlockRenderer { + + /** + * Renders the given blocks (block-state-)variant into the given blockModel, and sets the given blockColor to the + * color that represents the rendered block. + *

+ * Implementation Note:
+ * This method is guaranteed to be called only on one thread per BlockRenderer 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 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 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); + +} 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/blockmodel/BlockRendererFactory.java new file mode 100644 index 000000000..ade22c3ac --- /dev/null +++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRendererFactory.java @@ -0,0 +1,11 @@ +package de.bluecolored.bluemap.core.map.hires.blockmodel; + +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 BlockRendererFactory { + + BlockRenderer create(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings 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/blockmodel/BlockRendererType.java new file mode 100644 index 000000000..6881529cc --- /dev/null +++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockRendererType.java @@ -0,0 +1,56 @@ +package de.bluecolored.bluemap.core.map.hires.blockmodel; + +import de.bluecolored.bluemap.core.map.TextureGallery; +import de.bluecolored.bluemap.core.map.hires.RenderSettings; +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 BlockRendererType extends Keyed, BlockRendererFactory { + + BlockRendererType DEFAULT = new Impl(Key.bluemap("default"), ResourceModelRenderer::new); + BlockRendererType LIQUID = new Impl(Key.bluemap("liquid"), LiquidModelRenderer::new); + BlockRendererType MISSING = new Impl(Key.bluemap("missing"), MissingModelRenderer::new); + + Registry REGISTRY = new Registry<>( + DEFAULT, + LIQUID, + MISSING + ); + + /** + * If the loaded resourcepack does not have any resources for this blockState, this method will be called. + * If this method returns true, this renderer will be used to render the block instead of rendering the default + * black-purple "missing block" model. + * When rendering, the provided "variant" will always be bluemaps default "missing-block" resource. + * + *

+ * This can (and should only then) be used to provide a way of rendering blocks that are completely dynamically + * created by a mod, and there is no way to provide static block-state resources that point at the correct renderer. + *

+ * + * @param blockState The {@link BlockState} that was not found in the loaded resources. + * @return true if this renderer-type can render the provided {@link BlockState} despite missing resources. + */ + default boolean isFallbackFor(BlockState blockState) { + return false; + } + + @RequiredArgsConstructor + class Impl implements BlockRendererType { + + @Getter private final Key key; + private final BlockRendererFactory rendererFactory; + + @Override + public BlockRenderer 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/blockmodel/BlockStateModelFactory.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockStateModelRenderer.java similarity index 79% rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockStateModelFactory.java rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockStateModelRenderer.java index c3a2af9b4..1068fe0ee 100644 --- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockStateModelFactory.java +++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/BlockStateModelRenderer.java @@ -24,8 +24,10 @@ */ package de.bluecolored.bluemap.core.map.hires.blockmodel; +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.BlockModelView; +import de.bluecolored.bluemap.core.map.hires.TileModelView; import de.bluecolored.bluemap.core.map.hires.RenderSettings; import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack; import de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel.BlockModel; @@ -37,27 +39,25 @@ import java.util.ArrayList; import java.util.List; -public class BlockStateModelFactory { +public class BlockStateModelRenderer { private final ResourcePack resourcePack; - private final ResourceModelBuilder resourceModelBuilder; - private final LiquidModelBuilder liquidModelBuilder; + private final LoadingCache blockRenderers; private final List variants = new ArrayList<>(); - public BlockStateModelFactory(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) { + public BlockStateModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) { this.resourcePack = resourcePack; - - this.resourceModelBuilder = new ResourceModelBuilder(resourcePack, textureGallery, renderSettings); - this.liquidModelBuilder = new LiquidModelBuilder(resourcePack, textureGallery, renderSettings); + this.blockRenderers = Caffeine.newBuilder() + .build(type -> type.create(resourcePack, textureGallery, renderSettings)); } - public void render(BlockNeighborhood block, BlockModelView 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, BlockModelView blockModel, Color blockColor) { + public void render(BlockNeighborhood block, BlockState blockState, TileModelView blockModel, Color blockColor) { blockColor.set(0, 0, 0, 0, true); //shortcut for air @@ -79,7 +79,7 @@ public void render(BlockNeighborhood block, BlockState blockState, BlockModel } private final Color variantColor = new Color(); - private void renderModel(BlockNeighborhood block, BlockState blockState, BlockModelView blockModel, Color blockColor) { + private void renderModel(BlockNeighborhood block, BlockState blockState, TileModelView blockModel, Color blockColor) { int modelStart = blockModel.getStart(); var stateResource = resourcePack.getBlockState(blockState); @@ -98,11 +98,8 @@ private void renderModel(BlockNeighborhood block, BlockState blockState, Bloc variantColor.set(0f, 0f, 0f, 0f, true); - if (modelResource.isLiquid()) { - liquidModelBuilder.build(block, blockState, variant, blockModel.initialize(), variantColor); - } else { - resourceModelBuilder.build(block, variant, blockModel.initialize(), variantColor); - } + blockRenderers.get(modelResource.getRenderer()) + .render(block, variant, blockModel.initialize(), blockColor); if (variantColor.a > blockColorOpacity) blockColorOpacity = variantColor.a; diff --git a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelBuilder.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelRenderer.java similarity index 91% rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelBuilder.java rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelRenderer.java index f4b6d00c3..a26e66e56 100644 --- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelBuilder.java +++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/LiquidModelRenderer.java @@ -27,7 +27,7 @@ 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.BlockModelView; +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.resources.BlockColorCalculatorFactory; @@ -50,7 +50,7 @@ * A model builder for all liquid blocks */ @SuppressWarnings("DuplicatedCode") -public class LiquidModelBuilder { +public class LiquidModelRenderer implements BlockRenderer { private static final float BLOCK_SCALE = 1f / 16f; private static final MatrixM3f FLOWING_UV_SCALE = new MatrixM3f() .identity() @@ -68,11 +68,12 @@ public class LiquidModelBuilder { private BlockNeighborhood block; private BlockState blockState; + private boolean isWaterlogged, isWaterLike; private BlockModel modelResource; - private BlockModelView blockModel; + private TileModelView blockModel; private Color blockColor; - public LiquidModelBuilder(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) { + public LiquidModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) { this.resourcePack = resourcePack; this.textureGallery = textureGallery; this.renderSettings = renderSettings; @@ -92,9 +93,11 @@ public LiquidModelBuilder(ResourcePack resourcePack, TextureGallery textureGalle for (int i = 0; i < uvs.length; i++) uvs[i] = new VectorM2f(0, 0); } - public void build(BlockNeighborhood block, BlockState blockState, Variant variant, BlockModelView blockModel, Color color) { + public void render(BlockNeighborhood block, Variant variant, TileModelView blockModel, Color color) { this.block = block; - this.blockState = blockState; + this.blockState = block.getBlockState(); + this.isWaterlogged = blockState.isWaterlogged() || block.getProperties().isAlwaysWaterlogged(); + this.isWaterLike = blockState.isWater() || isWaterlogged; this.modelResource = variant.getModel().getResource(); this.blockModel = blockModel; this.blockColor = color; @@ -137,9 +140,7 @@ private void build() { int flowTextureId = textureGallery.get(flowTexturePath); tintcolor.set(1f, 1f, 1f, 1f, true); - if (blockState.isWater()) { - blockColorCalculator.getBlendedWaterColor(block, tintcolor); - } + if (isWaterLike) blockColorCalculator.getBlendedWaterColor(block, tintcolor); int modelStart = blockModel.getStart(); @@ -223,8 +224,15 @@ private boolean isLiquidBlockingBlock(BlockState blockState){ @SuppressWarnings("StringEquality") private boolean isSameLiquid(ExtendedBlock block){ - if (block.getBlockState().getFormatted() == this.blockState.getFormatted()) return true; - return this.blockState.isWater() && (block.getBlockState().isWaterlogged() || block.getProperties().isAlwaysWaterlogged()); + BlockState blockState = block.getBlockState(); + + if (this.isWaterlogged) + return blockState.isWater() || blockState.isWaterlogged() || block.getProperties().isAlwaysWaterlogged(); + + if (blockState.getFormatted() == this.blockState.getFormatted()) + return true; + + return this.isWaterLike && (blockState.isWaterlogged() || block.getProperties().isAlwaysWaterlogged()); } private float getLiquidBaseHeight(BlockState block){ @@ -249,7 +257,7 @@ private boolean createElementFace(Direction faceDir, VectorM3f c0, VectorM3f c1, blockModel.initialize(); blockModel.add(2); - TileModel tileModel = blockModel.getHiresTile(); + TileModel tileModel = blockModel.getTileModel(); int face1 = blockModel.getStart(); int face2 = face1 + 1; 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/blockmodel/MissingModelRenderer.java new file mode 100644 index 000000000..2e2382e71 --- /dev/null +++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/MissingModelRenderer.java @@ -0,0 +1,37 @@ +package de.bluecolored.bluemap.core.map.hires.blockmodel; + +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.blockstate.Variant; +import de.bluecolored.bluemap.core.util.math.Color; +import de.bluecolored.bluemap.core.world.BlockState; +import de.bluecolored.bluemap.core.world.block.BlockNeighborhood; + +public class MissingModelRenderer implements BlockRenderer { + + private static final LoadingCache BLOCK_RENDERER_TYPES = Caffeine.newBuilder() + .maximumSize(1000) + .build(blockState -> { + for (BlockRendererType type : BlockRendererType.REGISTRY.values()) + if (type.isFallbackFor(blockState)) return type; + return BlockRendererType.DEFAULT; + }); + + private final LoadingCache blockRenderers; + + public MissingModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) { + this.blockRenderers = Caffeine.newBuilder() + .build(type -> type.create(resourcePack, textureGallery, renderSettings)); + } + + @Override + 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/ResourceModelBuilder.java b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/ResourceModelRenderer.java similarity index 96% rename from core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/ResourceModelBuilder.java rename to core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/ResourceModelRenderer.java index d5cd5c49b..78024be8e 100644 --- a/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/ResourceModelBuilder.java +++ b/core/src/main/java/de/bluecolored/bluemap/core/map/hires/blockmodel/ResourceModelRenderer.java @@ -29,7 +29,7 @@ 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.BlockModelView; +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.resources.BlockColorCalculatorFactory; @@ -54,7 +54,7 @@ * This model builder creates a BlockStateModel using the information from parsed resource-pack json files. */ @SuppressWarnings("DuplicatedCode") -public class ResourceModelBuilder { +public class ResourceModelRenderer implements BlockRenderer { private static final float BLOCK_SCALE = 1f / 16f; private final ResourcePack resourcePack; @@ -71,11 +71,11 @@ public class ResourceModelBuilder { private BlockNeighborhood block; private Variant variant; private BlockModel modelResource; - private BlockModelView blockModel; + private TileModelView blockModel; private Color blockColor; private float blockColorOpacity; - public ResourceModelBuilder(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) { + public ResourceModelRenderer(ResourcePack resourcePack, TextureGallery textureGallery, RenderSettings renderSettings) { this.resourcePack = resourcePack; this.textureGallery = textureGallery; this.renderSettings = renderSettings; @@ -86,7 +86,7 @@ public ResourceModelBuilder(ResourcePack resourcePack, TextureGallery textureGal } private final MatrixM4f modelTransform = new MatrixM4f(); - public void build(BlockNeighborhood block, Variant variant, BlockModelView blockModel, Color color) { + public void render(BlockNeighborhood block, Variant variant, TileModelView blockModel, Color color) { this.block = block; this.blockModel = blockModel; this.blockColor = color; @@ -132,7 +132,7 @@ public void build(BlockNeighborhood block, Variant variant, BlockModelView bl } private final MatrixM4f modelElementTransform = new MatrixM4f(); - private void buildModelElementResource(Element element, BlockModelView blockModel) { + private void buildModelElementResource(Element element, TileModelView blockModel) { //create faces Vector3f from = element.getFrom(); @@ -215,7 +215,7 @@ private void createElementFace(Element element, Direction faceDir, VectorM3f c0, blockModel.initialize(); blockModel.add(2); - TileModel tileModel = blockModel.getHiresTile(); + TileModel tileModel = blockModel.getTileModel(); int face1 = blockModel.getStart(); int face2 = face1 + 1; 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 5dc82fedc..e22c29db3 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,6 +29,7 @@ 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.util.Direction; import de.bluecolored.bluemap.core.util.Key; @@ -64,6 +65,11 @@ public static GsonBuilder addAdapter(GsonBuilder builder) { GrassColorModifier.REGISTRY, Key.MINECRAFT_NAMESPACE, GrassColorModifier.NONE + )) + .registerTypeAdapter(BlockRendererType.class, new RegistryAdapter<>( + BlockRendererType.REGISTRY, + Key.BLUEMAP_NAMESPACE, + BlockRendererType.DEFAULT )); } 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/blockmodel/BlockModel.java index 6c6f63c48..c26a5b20f 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/blockmodel/BlockModel.java @@ -24,28 +24,35 @@ */ package de.bluecolored.bluemap.core.resources.pack.resourcepack.blockmodel; +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 org.jetbrains.annotations.Nullable; -import java.util.*; +import java.util.HashMap; +import java.util.Map; @SuppressWarnings({"FieldMayBeFinal", "FieldCanBeLocal"}) public class BlockModel { + private BlockRendererType renderer = BlockRendererType.DEFAULT; + private ResourcePath parent; private Map textures = new HashMap<>(); private Element[] elements; private boolean ambientocclusion = true; - private transient boolean liquid = false; private transient boolean culling = false; private transient boolean occluding = false; private BlockModel(){} + public BlockRendererType getRenderer() { + return renderer; + } + @Nullable public ResourcePath getParent() { return parent; @@ -64,10 +71,6 @@ public boolean isAmbientocclusion() { return ambientocclusion; } - public boolean isLiquid() { - return liquid; - } - public boolean isCulling() { return culling; } @@ -95,11 +98,6 @@ public synchronized void applyParent(ResourcePack resourcePack) { ResourcePath parentPath = this.parent; this.parent = null; - if (parentPath.getFormatted().equals("bluemap:builtin/liquid")) { - this.liquid = true; - return; - } - BlockModel parent = parentPath.getResource(resourcePack::getBlockModel); if (parent != null) { parent.applyParent(resourcePack); 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 9347b4e37..7f5ec17cf 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 @@ -40,6 +40,9 @@ public class Block> { private final LightData lightData = new LightData(-1, -1); private @Nullable Biome biome; + private boolean isBlockEntitySet; + private @Nullable BlockEntity blockEntity; + public Block(World world, int x, int y, int z) { set(world, x, y, z); } @@ -81,6 +84,8 @@ protected void reset() { this.blockState = null; this.lightData.set(-1, -1); this.biome = null; + this.isBlockEntitySet = false; + this.blockEntity = null; } public T add(int dx, int dy, int dz) { @@ -148,7 +153,11 @@ public int getBlockLightLevel() { } public @Nullable BlockEntity getBlockEntity() { - return getChunk().getBlockEntity(x, y, z); + if (!isBlockEntitySet) { + blockEntity = getChunk().getBlockEntity(x, y, z); + isBlockEntitySet = true; + } + return blockEntity; } @Override diff --git a/core/src/main/resourceExtensions/assets/bluemap/models/block/missing.json b/core/src/main/resourceExtensions/assets/bluemap/models/block/missing.json index 206494b39..e185348a5 100644 --- a/core/src/main/resourceExtensions/assets/bluemap/models/block/missing.json +++ b/core/src/main/resourceExtensions/assets/bluemap/models/block/missing.json @@ -1,4 +1,5 @@ { + "renderer": "bluemap:missing", "parent": "block/cube_all", "textures": { "all": "bluemap:block/missing" diff --git a/core/src/main/resourceExtensions/assets/minecraft/models/block/lava.json b/core/src/main/resourceExtensions/assets/minecraft/models/block/lava.json index a514d057f..51c0b0d9e 100644 --- a/core/src/main/resourceExtensions/assets/minecraft/models/block/lava.json +++ b/core/src/main/resourceExtensions/assets/minecraft/models/block/lava.json @@ -1,5 +1,5 @@ { - "parent": "bluemap:builtin/liquid", + "renderer": "bluemap:liquid", "textures": { "particle": "block/lava_still", "still": "block/lava_still", diff --git a/core/src/main/resourceExtensions/assets/minecraft/models/block/water.json b/core/src/main/resourceExtensions/assets/minecraft/models/block/water.json index 0c0fc9a8f..47316ea37 100644 --- a/core/src/main/resourceExtensions/assets/minecraft/models/block/water.json +++ b/core/src/main/resourceExtensions/assets/minecraft/models/block/water.json @@ -1,5 +1,5 @@ { - "parent": "bluemap:builtin/liquid", + "renderer": "bluemap:liquid", "textures": { "particle": "block/water_still", "still": "block/water_still",