mirror of
https://github.com/BlueMap-Minecraft/BlueMap.git
synced 2024-11-22 02:26:00 +01:00
Add first iteration of custom block-renderers (#561)
This commit is contained in:
parent
b26b908992
commit
c2fa00db5b
@ -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<BlockStateModelFactory> threadLocalModelFactory;
|
||||
private final ThreadLocal<BlockStateModelRenderer> 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));
|
||||
|
@ -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() {
|
@ -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.
|
||||
* <p>
|
||||
* <b>Implementation Note:</b><br>
|
||||
* This method is guaranteed to be called only on <b>one thread per BlockRenderer instance</b>, so you can use this
|
||||
* for optimizations.<br>
|
||||
* 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.
|
||||
* </p>
|
||||
* @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);
|
||||
|
||||
}
|
@ -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);
|
||||
|
||||
}
|
@ -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<BlockRendererType> 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.
|
||||
*
|
||||
* <p>
|
||||
* 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.
|
||||
* </p>
|
||||
*
|
||||
* @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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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<BlockRendererType, BlockRenderer> blockRenderers;
|
||||
|
||||
private final List<Variant> 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;
|
@ -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;
|
||||
|
@ -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<BlockState, BlockRendererType> 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<BlockRendererType, BlockRenderer> 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);
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
|
@ -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
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -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<BlockModel> parent;
|
||||
private Map<String, TextureVariable> 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<BlockModel> 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<BlockModel> 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);
|
||||
|
@ -40,6 +40,9 @@ public class Block<T extends Block<T>> {
|
||||
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
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"renderer": "bluemap:missing",
|
||||
"parent": "block/cube_all",
|
||||
"textures": {
|
||||
"all": "bluemap:block/missing"
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"parent": "bluemap:builtin/liquid",
|
||||
"renderer": "bluemap:liquid",
|
||||
"textures": {
|
||||
"particle": "block/lava_still",
|
||||
"still": "block/lava_still",
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"parent": "bluemap:builtin/liquid",
|
||||
"renderer": "bluemap:liquid",
|
||||
"textures": {
|
||||
"particle": "block/water_still",
|
||||
"still": "block/water_still",
|
||||
|
Loading…
Reference in New Issue
Block a user