diff --git a/src/main/java/nova/core/render/pipeline/ConnectedTextureRenderPipeline.java b/src/main/java/nova/core/render/pipeline/ConnectedTextureRenderPipeline.java index 27206fd9d..2d33ed60d 100644 --- a/src/main/java/nova/core/render/pipeline/ConnectedTextureRenderPipeline.java +++ b/src/main/java/nova/core/render/pipeline/ConnectedTextureRenderPipeline.java @@ -35,6 +35,8 @@ import java.util.function.Predicate; import java.util.function.Supplier; +// TODO: create a CTM pipeline builder at some point, to automate construction of CTM pipelines +// (there are 47 different CTM textures for a block which connects omni-directionally, writing that manually would get annoying really fast) public class ConnectedTextureRenderPipeline extends BlockRenderPipeline { public final Block block; @@ -42,16 +44,14 @@ public class ConnectedTextureRenderPipeline extends BlockRenderPipeline { /** * The mask the represents which sides the block should render its connected texture. - * E.g: 000000 will render all directions + * E.g: 00000000 will render all directions */ public Supplier connectMask; /** - * A mask of which sides the connected texture renderer should render. - * Each bit corresponds to a direction. - * E.g: 000011 will render top and bottom + * A filter of which sides the connected texture renderer should render. */ - public int faceMask = 0xff; + public Predicate faceFilter = dir -> true; public ConnectedTextureRenderPipeline(Block block, Texture edgeTexture) { super(block); @@ -61,7 +61,10 @@ public ConnectedTextureRenderPipeline(Block block, Texture edgeTexture) { connectMask = () -> { if (this.block.components.has(BlockTransform.class)) { return Arrays.stream(Direction.VALID_DIRECTIONS) - .filter(d -> this.block.world().getBlock(this.block.position().add(d.toVector())).get().sameType(this.block)) + .filter(d -> { + Optional b = this.block.world().getBlock(this.block.position().add(d.toVector())); + return b.isPresent() && b.get().sameType(this.block); + }) .map(d -> 1 << d.ordinal()) .reduce(0, (b, a) -> a | b); } @@ -76,7 +79,7 @@ public ConnectedTextureRenderPipeline(Block block, Texture edgeTexture) { //Render the block edge for (Direction dir : Direction.VALID_DIRECTIONS) - if ((faceMask & (1 << dir.ordinal())) != 0) { + if (faceFilter.test(dir)) { renderFace(dir, model); } }; @@ -88,21 +91,29 @@ public ConnectedTextureRenderPipeline withConnectMask(Supplier connectM } /** - * Set the mask used to determine if this pipeline should handle these sides. + * Set the filter used to determine if this pipeline should handle these sides. * - * @param faceMask A mask of which sides the connected texture renderer should render. + * @param faceFilter A filter of which sides the connected texture renderer should render. * @return this */ - public ConnectedTextureRenderPipeline withFaceMask(Predicate faceMask) { - int faceMaskInt = 0; - for (int i = 0; i < 6; i++) - faceMaskInt |= (faceMask.test(Direction.fromOrdinal(i)) ? 1 : 0); - this.faceMask = faceMaskInt; + public ConnectedTextureRenderPipeline withFaceFilter(Predicate faceFilter) { + this.faceFilter = faceFilter; return this; } /** - * Set the mask used to determine if this pipeline should handle these sides. + * Set the filter used to determine if this pipeline should handle these sides. + * + * @param faces An array of which sides the connected texture renderer should render. + * @return this + */ + public ConnectedTextureRenderPipeline withFaces(Direction... faces) { + this.faceFilter = dir -> Arrays.stream(faces).anyMatch(d -> d == dir); + return this; + } + + /** + * Set the filter used to determine if this pipeline should handle these sides. * * @param faceMask A mask of which sides the connected texture renderer should render. * Each bit corresponds to a direction. @@ -110,11 +121,16 @@ public ConnectedTextureRenderPipeline withFaceMask(Predicate faceMask * @return this */ public ConnectedTextureRenderPipeline withFaceMask(int faceMask) { - this.faceMask = faceMask; + this.faceFilter = dir -> (faceMask & (1 << dir.ordinal())) != 0; return this; } - //Apply connected texture on top face + /** + * Apply connected texture on top face. + * + * @param direction the direction. + * @param model the model. + */ protected void renderFace(Direction direction, Model model) { for (int r = 0; r < 4; r++) { Cuboid bound = bounds.get() diff --git a/src/main/java/nova/core/util/Pipeline.java b/src/main/java/nova/core/util/Pipeline.java index fb776f7b0..dd8da422e 100644 --- a/src/main/java/nova/core/util/Pipeline.java +++ b/src/main/java/nova/core/util/Pipeline.java @@ -8,7 +8,7 @@ * @author Calclavia */ public class Pipeline { - protected Optional prev = Optional.empty(); + protected Optional> prev = Optional.empty(); protected Consumer consumer = model -> {}; @@ -32,7 +32,7 @@ public Pipeline(Consumer consumer) { * @param stream The stream to apply. * @return The new RenderStream */ - public > T apply(T stream) { + public > T apply(T stream) { stream.prev = Optional.of(this); return stream; }