diff --git a/gradle.properties b/gradle.properties index 6ceba3a..4054115 100644 --- a/gradle.properties +++ b/gradle.properties @@ -10,7 +10,7 @@ yarn_mappings=1.21+build.2 loader_version=0.15.11 # Mod Properties -mod_version=0.9.5.2 +mod_version=0.9.6 maven_group=quimufu.colourful-portalRepresentations archives_base_name=colourful-portalRepresentations diff --git a/src/main/java/quimufu/colourful_portals/ColourfulPortalsMod.java b/src/main/java/quimufu/colourful_portals/ColourfulPortalsMod.java index 4cba5a4..26182e9 100644 --- a/src/main/java/quimufu/colourful_portals/ColourfulPortalsMod.java +++ b/src/main/java/quimufu/colourful_portals/ColourfulPortalsMod.java @@ -22,6 +22,9 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.world.BlockView; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import quimufu.colourful_portals.client.CommonPortalFluidRenderer; +import quimufu.colourful_portals.client.CommonPortalFluidRendererV1; +import quimufu.colourful_portals.client.CommonPortalFluidRendererV2; import quimufu.colourful_portals.config.ColourfulPortalConfig; import quimufu.colourful_portals.portal.*; import quimufu.colourful_portals.portal_fluid.PortalFluid; @@ -65,11 +68,9 @@ public class ColourfulPortalsMod implements ModInitializer { public void onInitialize() { LOGGER.info("Colouring Portals..."); MidnightConfig.init(MOD_ID, ColourfulPortalConfig.class); + ColourfulPortalConfig.registerListener(this::onConfigUpdate); - for (String id : ColourfulPortalConfig.getAllPortalBlocks()) { - LOGGER.info(id); - PORTAL_BLOCKS.add(Identifier.tryParse(id)); - } + onConfigUpdate(); if (!ColourfulPortalConfig.disableImmersivePortals && hasImmPtl()) { Registry.register(PORTAL_LINKING_SYSTEM_BUILDER_REGISTRY, ImmersivePortalsLinkingSystem.IMMERSIVE_PORTALS_LINKING_SYSTEM, new PrioritizedPortalLinkingSystemBuilder(ImmersivePortalsLinkingSystem::new, 100)); } @@ -97,6 +98,14 @@ public class ColourfulPortalsMod implements ModInitializer { LOGGER.info("Portals Colourful!"); } + private void onConfigUpdate() { + PORTAL_BLOCKS.clear(); + for (String id : ColourfulPortalConfig.getAllPortalBlocks()) { + LOGGER.info(id); + PORTAL_BLOCKS.add(Identifier.tryParse(id)); + } + } + private boolean hasImmPtl() { try { Class.forName("qouteall.imm_ptl.core.IPModMain", false, this.getClass().getClassLoader()); diff --git a/src/main/java/quimufu/colourful_portals/ColourfulPortalsModClient.java b/src/main/java/quimufu/colourful_portals/ColourfulPortalsModClient.java index aba2fed..dd3cb72 100644 --- a/src/main/java/quimufu/colourful_portals/ColourfulPortalsModClient.java +++ b/src/main/java/quimufu/colourful_portals/ColourfulPortalsModClient.java @@ -4,13 +4,30 @@ import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.blockrenderlayer.v1.BlockRenderLayerMap; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; import net.minecraft.client.render.RenderLayer; +import quimufu.colourful_portals.client.CommonPortalFluidRenderer; +import quimufu.colourful_portals.client.CommonPortalFluidRendererV1; +import quimufu.colourful_portals.client.CommonPortalFluidRendererV2; import quimufu.colourful_portals.client.PortalFluidRenderHandler; +import quimufu.colourful_portals.config.ColourfulPortalConfig; public class ColourfulPortalsModClient implements ClientModInitializer { + public static ThreadLocal FLUID_RENDERER = ThreadLocal.withInitial(CommonPortalFluidRendererV2::new); + public void onInitializeClient() { BlockRenderLayerMap.INSTANCE.putBlock(ColourfulPortalsMod.PORTAL_BLOCK, RenderLayer.getTranslucent()); BlockRenderLayerMap.INSTANCE.putFluid(ColourfulPortalsMod.PORTAL_FLUID, RenderLayer.getTranslucent()); FluidRenderHandlerRegistry.INSTANCE.register(ColourfulPortalsMod.PORTAL_FLUID, new PortalFluidRenderHandler()); + ColourfulPortalConfig.registerListener(this::onConfigUpdate); + onConfigUpdate(); + } + + private void onConfigUpdate() { + if(ColourfulPortalConfig.blockyPortalFluid){ + FLUID_RENDERER = ThreadLocal.withInitial(CommonPortalFluidRendererV1::new); + } else { + FLUID_RENDERER = ThreadLocal.withInitial(CommonPortalFluidRendererV2::new); + } + } } \ No newline at end of file diff --git a/src/main/java/quimufu/colourful_portals/client/AlphaBlendingAnimator.java b/src/main/java/quimufu/colourful_portals/client/AlphaBlendingAnimator.java index bc3fb0f..76813d5 100644 --- a/src/main/java/quimufu/colourful_portals/client/AlphaBlendingAnimator.java +++ b/src/main/java/quimufu/colourful_portals/client/AlphaBlendingAnimator.java @@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable; import java.util.List; /** - * This code is mostly copies from minecraft source. it is owned by mojang. + * This code is mostly copies from minecraft source. It is owned by mojang. */ public class AlphaBlendingAnimator implements Animator { int frame; diff --git a/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRenderer.java b/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRenderer.java index 269471f..12eebbe 100644 --- a/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRenderer.java +++ b/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRenderer.java @@ -1,251 +1,14 @@ package quimufu.colourful_portals.client; -import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; -import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; -import net.minecraft.block.BlockState; -import net.minecraft.client.texture.Sprite; import net.minecraft.fluid.FluidState; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import net.minecraft.world.BlockRenderView; -import quimufu.colourful_portals.ColourfulPortalsMod; -import quimufu.colourful_portals.portal_fluid.PortalFluid; +import org.joml.Vector3f; -public class CommonPortalFluidRenderer { - - private Sprite sprite = null; - private final float[] uIu2IvIv2 = new float[4]; - - public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos, BlockPos offset, VertexEater vertexEater) { - - FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(fluidState.getFluid()); - sprite = handler.getFluidSprites(null, null, fluidState)[0]; - //from - float x = 0; - float y = 0; - float z = 0; - //to - float x2 = 1; - float y2 = 1; - float z2 = 1; - - Direction.Axis axis = fluidState.get(PortalFluid.AXIS).getAxis(); - int amount = fluidState.get(PortalFluid.AMOUNT); - if (amount == 0) - return false; - final float offsetInSquishedDir = (16 - amount) / 32f; - if (axis != null) { - switch (axis) { - case X -> { - x += offsetInSquishedDir; - x2 -= offsetInSquishedDir; - } - case Y -> { - y += offsetInSquishedDir; - y2 -= offsetInSquishedDir; - } - case Z -> { - z += offsetInSquishedDir; - z2 -= offsetInSquishedDir; - } - } - - } - - boolean ret = false; - for (Direction direction : Direction.values()) { - - BlockPos neighbourPos = pos.offset(direction); - BlockState neighbour = world.getBlockState(neighbourPos); - FluidState neighbourFluidState = neighbour.getFluidState(); - if (axis == null || direction.getAxis() != axis) { - if (neighbour.isSideSolidFullSquare(world, neighbourPos, direction.getOpposite()) - && neighbour.isOpaque()) { - continue; - } - if (neighbourFluidState.isOf(ColourfulPortalsMod.PORTAL_FLUID) - && neighbourFluidState.get(PortalFluid.AMOUNT) >= amount) { - continue; - } - } - if (axis != null && direction.getAxis() != axis) { - - int neighbourAmount; - if (neighbourFluidState.isOf(ColourfulPortalsMod.PORTAL_FLUID) - && (neighbourAmount = neighbourFluidState.get(PortalFluid.AMOUNT)) < amount) { - //draw side as two little silvers, adapting our width to neighbour width - float neighbourOffsetInSquishedDir = (16 - neighbourAmount) / 32F; - drawSilvers(vertexEater, direction, axis, offsetInSquishedDir, neighbourOffsetInSquishedDir, offset, (amount & 1) == 1); - ret = true; - continue; - } - calcSquishedUVs(axis, 1.f - offsetInSquishedDir, offsetInSquishedDir, direction, (amount & 1) == 1); - } else { - uIu2IvIv2[0] = sprite.getFrameU(0.F); - uIu2IvIv2[1] = sprite.getFrameU(1.F); - uIu2IvIv2[2] = sprite.getFrameV(0.F); - uIu2IvIv2[3] = sprite.getFrameV(1.F); - - } - drawSide(vertexEater, x, y, z, x2, y2, z2, direction, uIu2IvIv2[0], uIu2IvIv2[2], uIu2IvIv2[1], uIu2IvIv2[3], offset); - ret = true; - - } - return ret; - } - - private void calcSquishedUVs(Direction.Axis axis, float squishedTop, float squishedBottom, Direction direction, boolean odd) { - switch (axis) { - case X -> { - if (odd) { - uIu2IvIv2[0] = sprite.getFrameU(1.F/32.F + squishedBottom); - uIu2IvIv2[1] = sprite.getFrameU(1.F/32.F + squishedTop); - - } else { - uIu2IvIv2[0] = sprite.getFrameU(0.F + squishedBottom); - uIu2IvIv2[1] = sprite.getFrameU(squishedTop); - } - uIu2IvIv2[2] = sprite.getFrameV(0.F); - uIu2IvIv2[3] = sprite.getFrameV(1.F); - } - case Z -> { - if (direction.getAxis() == Direction.Axis.Y) { - if (odd) { - uIu2IvIv2[2] = sprite.getFrameV(1.F/32.F + squishedBottom); - uIu2IvIv2[3] = sprite.getFrameV(1.F/32.F + squishedTop); - - } else { - uIu2IvIv2[2] = sprite.getFrameV(squishedBottom); - uIu2IvIv2[3] = sprite.getFrameV(squishedTop); - } - uIu2IvIv2[0] = sprite.getFrameU(0.F); - uIu2IvIv2[1] = sprite.getFrameU(1.F); - } else { - if (odd) { - uIu2IvIv2[0] = sprite.getFrameU(1.F/32.F + squishedBottom); - uIu2IvIv2[1] = sprite.getFrameU(1.F/32.F + squishedTop); - - } else { - uIu2IvIv2[0] = sprite.getFrameU(squishedBottom); - uIu2IvIv2[1] = sprite.getFrameU(squishedTop); - } - uIu2IvIv2[2] = sprite.getFrameV(0.F); - uIu2IvIv2[3] = sprite.getFrameV(1.F); - - } - } - case Y -> { - if (odd) { - uIu2IvIv2[2] = sprite.getFrameV(1.F/32.F + squishedBottom); - uIu2IvIv2[3] = sprite.getFrameV(1.F/32.F + squishedTop); - - } else { - uIu2IvIv2[2] = sprite.getFrameV(squishedBottom); - uIu2IvIv2[3] = sprite.getFrameV(squishedTop); - } - uIu2IvIv2[0] = sprite.getFrameU(0.F); - uIu2IvIv2[1] = sprite.getFrameU(1.F); - } - default -> throw new IllegalStateException("Unexpected value: " + axis); - } - } - - - private void drawSilvers(VertexEater buffers, Direction direction, Direction.Axis axis, float offsetInSquishedDir, float neighbourOffsetInSquishedDir, BlockPos offset, boolean odd) { - - float x = 0F; - float x2 = 1F; - float y = 0F; - float y2 = 1F; - float z = 0F; - float z2 = 1F; - switch (axis) { - case X -> { - x = offsetInSquishedDir; - x2 = neighbourOffsetInSquishedDir; - } - case Y -> { - y = offsetInSquishedDir; - y2 = neighbourOffsetInSquishedDir; - } - case Z -> { - z = offsetInSquishedDir; - z2 = neighbourOffsetInSquishedDir; - } - } - calcSquishedUVs(axis, offsetInSquishedDir, neighbourOffsetInSquishedDir, direction, odd); - drawSide(buffers, x, y, z, x2, y2, z2, direction, uIu2IvIv2[0], uIu2IvIv2[2], uIu2IvIv2[1], uIu2IvIv2[3], offset); - - switch (axis) { - case X -> { - x = 1F - neighbourOffsetInSquishedDir; - x2 = 1F - offsetInSquishedDir; - } - case Y -> { - y = 1F - neighbourOffsetInSquishedDir; - y2 = 1F - offsetInSquishedDir; - } - case Z -> { - z = 1F - neighbourOffsetInSquishedDir; - z2 = 1F - offsetInSquishedDir; - } - } - calcSquishedUVs(axis, 1.f - neighbourOffsetInSquishedDir,1.f - offsetInSquishedDir , direction, odd); - drawSide(buffers, x, y, z, x2, y2, z2, direction, uIu2IvIv2[0], uIu2IvIv2[2], uIu2IvIv2[1], uIu2IvIv2[3], offset); - } - - private void drawSide(VertexEater vertexConsumer, float x, float y, float z, float x2, float y2, float z2, Direction direction, float frameU, float frameV, float frameU2, float frameV2, BlockPos offset) { - vertexConsumer.setSprite(sprite); - switch (direction) { - case DOWN -> { - vertexConsumer.eatVertex(x, y, z, frameU, frameV2); - vertexConsumer.eatVertex( x2, y, z, frameU2, frameV2); - vertexConsumer.eatVertex( x2, y, z2, frameU2, frameV); - vertexConsumer.eatVertex( x, y, z2, frameU, frameV); - vertexConsumer.drawQuad(offset, direction); - } - case UP -> { - vertexConsumer.eatVertex( x, y2, z2, frameU, frameV2); - vertexConsumer.eatVertex( x2, y2, z2, frameU2, frameV2); - vertexConsumer.eatVertex( x2, y2, z, frameU2, frameV); - vertexConsumer.eatVertex( x, y2, z, frameU, frameV); - vertexConsumer.drawQuad(offset, direction); - } - case NORTH -> { - vertexConsumer.eatVertex( x, y2, z, frameU, frameV); - vertexConsumer.eatVertex( x2, y2, z, frameU2, frameV); - vertexConsumer.eatVertex( x2, y, z, frameU2, frameV2); - vertexConsumer.eatVertex( x, y, z, frameU, frameV2); - vertexConsumer.drawQuad(offset, direction); - } - case SOUTH -> { - vertexConsumer.eatVertex( x, y, z2, frameU, frameV); - vertexConsumer.eatVertex( x2, y, z2, frameU2, frameV); - vertexConsumer.eatVertex( x2, y2, z2, frameU2, frameV2); - vertexConsumer.eatVertex( x, y2, z2, frameU, frameV2); - vertexConsumer.drawQuad(offset, direction); - } - case WEST -> { - vertexConsumer.eatVertex( x, y, z, frameU, frameV); - vertexConsumer.eatVertex( x, y, z2, frameU2, frameV); - vertexConsumer.eatVertex( x, y2, z2, frameU2, frameV2); - vertexConsumer.eatVertex( x, y2, z, frameU, frameV2); - vertexConsumer.drawQuad(offset, direction); - } - case EAST -> { - vertexConsumer.eatVertex( x2, y2, z, frameU, frameV); - vertexConsumer.eatVertex( x2, y2, z2, frameU2, frameV); - vertexConsumer.eatVertex( x2, y, z2, frameU2, frameV2); - vertexConsumer.eatVertex( x2, y, z, frameU, frameV2); - vertexConsumer.drawQuad(offset, direction); - } - } - } - - public interface VertexEater { - - void setSprite(Sprite sprite); - void eatVertex(float x, float y, float z, float frameU, float frameV); - void drawQuad(BlockPos offset, Direction direction); - } +public interface CommonPortalFluidRenderer { + boolean render(BlockRenderView world, + FluidState fluidState, + BlockPos pos, + Vector3f offset, + VertexEater vertexEater); } diff --git a/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRendererV1.java b/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRendererV1.java new file mode 100644 index 0000000..99ea8b6 --- /dev/null +++ b/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRendererV1.java @@ -0,0 +1,255 @@ +package quimufu.colourful_portals.client; + +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; +import net.minecraft.block.BlockState; +import net.minecraft.client.texture.Sprite; +import net.minecraft.fluid.FluidState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockRenderView; +import org.joml.Quaternionf; +import org.joml.Vector3f; +import quimufu.colourful_portals.ColourfulPortalsMod; +import quimufu.colourful_portals.portal_fluid.PortalFluid; + +public class CommonPortalFluidRendererV1 implements CommonPortalFluidRenderer { + + public static final Quaternionf IDENTITY = new Quaternionf(); + private Sprite sprite = null; + private final float[] uIu2IvIv2 = new float[4]; + + @Override + public boolean render(BlockRenderView world, + FluidState fluidState, + BlockPos pos, + Vector3f offset, + VertexEater vertexEater) { + + offset.sub(0.5f,0.5f,0.5f); + + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(fluidState.getFluid()); + sprite = handler.getFluidSprites(null, null, fluidState)[0]; + //from + float x = 0; + float y = 0; + float z = 0; + //to + float x2 = 1; + float y2 = 1; + float z2 = 1; + + Direction.Axis axis = fluidState.get(PortalFluid.AXIS).getAxis(); + int amount = fluidState.get(PortalFluid.AMOUNT); + if (amount == 0) + return false; + final float offsetInSquishedDir = (16 - amount) / 32f; + if (axis != null) { + switch (axis) { + case X -> { + x += offsetInSquishedDir; + x2 -= offsetInSquishedDir; + } + case Y -> { + y += offsetInSquishedDir; + y2 -= offsetInSquishedDir; + } + case Z -> { + z += offsetInSquishedDir; + z2 -= offsetInSquishedDir; + } + } + + } + + boolean ret = false; + for (Direction direction : Direction.values()) { + + BlockPos neighbourPos = pos.offset(direction); + BlockState neighbour = world.getBlockState(neighbourPos); + FluidState neighbourFluidState = neighbour.getFluidState(); + if (axis == null || direction.getAxis() != axis) { + if (neighbour.isSideSolidFullSquare(world, neighbourPos, direction.getOpposite()) + && neighbour.isOpaque()) { + continue; + } + if (neighbourFluidState.isOf(ColourfulPortalsMod.PORTAL_FLUID) + && neighbourFluidState.get(PortalFluid.AMOUNT) >= amount) { + continue; + } + } + if (axis != null && direction.getAxis() != axis) { + + int neighbourAmount; + if (neighbourFluidState.isOf(ColourfulPortalsMod.PORTAL_FLUID) + && (neighbourAmount = neighbourFluidState.get(PortalFluid.AMOUNT)) < amount) { + //draw side as two little silvers, adapting our width to neighbour width + float neighbourOffsetInSquishedDir = (16 - neighbourAmount) / 32F; + drawSilvers(vertexEater, direction, axis, offsetInSquishedDir, neighbourOffsetInSquishedDir, offset, (amount & 1) == 1); + ret = true; + continue; + } + calcSquishedUVs(axis, 1.f - offsetInSquishedDir, offsetInSquishedDir, direction, (amount & 1) == 1); + } else { + uIu2IvIv2[0] = sprite.getFrameU(0.F); + uIu2IvIv2[1] = sprite.getFrameU(1.F); + uIu2IvIv2[2] = sprite.getFrameV(0.F); + uIu2IvIv2[3] = sprite.getFrameV(1.F); + + } + drawSide(vertexEater, x, y, z, x2, y2, z2, direction, uIu2IvIv2[0], uIu2IvIv2[2], uIu2IvIv2[1], uIu2IvIv2[3], offset); + ret = true; + + } + return ret; + } + + private void calcSquishedUVs(Direction.Axis axis, float squishedTop, float squishedBottom, Direction direction, boolean odd) { + switch (axis) { + case X -> { + if (odd) { + uIu2IvIv2[0] = sprite.getFrameU(1.F / 32.F + squishedBottom); + uIu2IvIv2[1] = sprite.getFrameU(1.F / 32.F + squishedTop); + + } else { + uIu2IvIv2[0] = sprite.getFrameU(0.F + squishedBottom); + uIu2IvIv2[1] = sprite.getFrameU(squishedTop); + } + uIu2IvIv2[2] = sprite.getFrameV(0.F); + uIu2IvIv2[3] = sprite.getFrameV(1.F); + } + case Z -> { + if (direction.getAxis() == Direction.Axis.Y) { + if (odd) { + uIu2IvIv2[2] = sprite.getFrameV(1.F / 32.F + squishedBottom); + uIu2IvIv2[3] = sprite.getFrameV(1.F / 32.F + squishedTop); + + } else { + uIu2IvIv2[2] = sprite.getFrameV(squishedBottom); + uIu2IvIv2[3] = sprite.getFrameV(squishedTop); + } + uIu2IvIv2[0] = sprite.getFrameU(0.F); + uIu2IvIv2[1] = sprite.getFrameU(1.F); + } else { + if (odd) { + uIu2IvIv2[0] = sprite.getFrameU(1.F / 32.F + squishedBottom); + uIu2IvIv2[1] = sprite.getFrameU(1.F / 32.F + squishedTop); + + } else { + uIu2IvIv2[0] = sprite.getFrameU(squishedBottom); + uIu2IvIv2[1] = sprite.getFrameU(squishedTop); + } + uIu2IvIv2[2] = sprite.getFrameV(0.F); + uIu2IvIv2[3] = sprite.getFrameV(1.F); + + } + } + case Y -> { + if (odd) { + uIu2IvIv2[2] = sprite.getFrameV(1.F / 32.F + squishedBottom); + uIu2IvIv2[3] = sprite.getFrameV(1.F / 32.F + squishedTop); + + } else { + uIu2IvIv2[2] = sprite.getFrameV(squishedBottom); + uIu2IvIv2[3] = sprite.getFrameV(squishedTop); + } + uIu2IvIv2[0] = sprite.getFrameU(0.F); + uIu2IvIv2[1] = sprite.getFrameU(1.F); + } + default -> throw new IllegalStateException("Unexpected value: " + axis); + } + } + + + private void drawSilvers(VertexEater buffers, Direction direction, Direction.Axis axis, float offsetInSquishedDir, float neighbourOffsetInSquishedDir, Vector3f offset, boolean odd) { + + float x = 0F; + float x2 = 1F; + float y = 0F; + float y2 = 1F; + float z = 0F; + float z2 = 1F; + switch (axis) { + case X -> { + x = offsetInSquishedDir; + x2 = neighbourOffsetInSquishedDir; + } + case Y -> { + y = offsetInSquishedDir; + y2 = neighbourOffsetInSquishedDir; + } + case Z -> { + z = offsetInSquishedDir; + z2 = neighbourOffsetInSquishedDir; + } + } + calcSquishedUVs(axis, offsetInSquishedDir, neighbourOffsetInSquishedDir, direction, odd); + drawSide(buffers, x, y, z, x2, y2, z2, direction, uIu2IvIv2[0], uIu2IvIv2[2], uIu2IvIv2[1], uIu2IvIv2[3], offset); + + switch (axis) { + case X -> { + x = 1F - neighbourOffsetInSquishedDir; + x2 = 1F - offsetInSquishedDir; + } + case Y -> { + y = 1F - neighbourOffsetInSquishedDir; + y2 = 1F - offsetInSquishedDir; + } + case Z -> { + z = 1F - neighbourOffsetInSquishedDir; + z2 = 1F - offsetInSquishedDir; + } + } + calcSquishedUVs(axis, 1.f - neighbourOffsetInSquishedDir, 1.f - offsetInSquishedDir, direction, odd); + drawSide(buffers, x, y, z, x2, y2, z2, direction, uIu2IvIv2[0], uIu2IvIv2[2], uIu2IvIv2[1], uIu2IvIv2[3], offset); + } + + private void drawSide(VertexEater vertexConsumer, float x, float y, float z, float x2, float y2, float z2, Direction direction, float frameU, float frameV, float frameU2, float frameV2, Vector3f offset) { + vertexConsumer.setSprite(sprite); + switch (direction) { + case DOWN -> { + vertexConsumer.eatVertex(x, y, z, frameU, frameV2); + vertexConsumer.eatVertex(x2, y, z, frameU2, frameV2); + vertexConsumer.eatVertex(x2, y, z2, frameU2, frameV); + vertexConsumer.eatVertex(x, y, z2, frameU, frameV); + vertexConsumer.drawQuad(offset, IDENTITY, direction); + } + case UP -> { + vertexConsumer.eatVertex(x, y2, z2, frameU, frameV2); + vertexConsumer.eatVertex(x2, y2, z2, frameU2, frameV2); + vertexConsumer.eatVertex(x2, y2, z, frameU2, frameV); + vertexConsumer.eatVertex(x, y2, z, frameU, frameV); + vertexConsumer.drawQuad(offset, IDENTITY, direction); + } + case NORTH -> { + vertexConsumer.eatVertex(x, y2, z, frameU, frameV); + vertexConsumer.eatVertex(x2, y2, z, frameU2, frameV); + vertexConsumer.eatVertex(x2, y, z, frameU2, frameV2); + vertexConsumer.eatVertex(x, y, z, frameU, frameV2); + vertexConsumer.drawQuad(offset, IDENTITY, direction); + } + case SOUTH -> { + vertexConsumer.eatVertex(x, y, z2, frameU, frameV); + vertexConsumer.eatVertex(x2, y, z2, frameU2, frameV); + vertexConsumer.eatVertex(x2, y2, z2, frameU2, frameV2); + vertexConsumer.eatVertex(x, y2, z2, frameU, frameV2); + vertexConsumer.drawQuad(offset, IDENTITY, direction); + } + case WEST -> { + vertexConsumer.eatVertex(x, y, z, frameU, frameV); + vertexConsumer.eatVertex(x, y, z2, frameU2, frameV); + vertexConsumer.eatVertex(x, y2, z2, frameU2, frameV2); + vertexConsumer.eatVertex(x, y2, z, frameU, frameV2); + vertexConsumer.drawQuad(offset, IDENTITY, direction); + } + case EAST -> { + vertexConsumer.eatVertex(x2, y2, z, frameU, frameV); + vertexConsumer.eatVertex(x2, y2, z2, frameU2, frameV); + vertexConsumer.eatVertex(x2, y, z2, frameU2, frameV2); + vertexConsumer.eatVertex(x2, y, z, frameU, frameV2); + vertexConsumer.drawQuad(offset, IDENTITY, direction); + } + } + } + +} diff --git a/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRendererV2.java b/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRendererV2.java new file mode 100644 index 0000000..26f198d --- /dev/null +++ b/src/main/java/quimufu/colourful_portals/client/CommonPortalFluidRendererV2.java @@ -0,0 +1,352 @@ +package quimufu.colourful_portals.client; + +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; +import net.minecraft.block.BlockState; +import net.minecraft.client.texture.Sprite; +import net.minecraft.fluid.FluidState; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.world.BlockRenderView; +import org.joml.Quaternionf; +import org.joml.Vector3f; +import quimufu.colourful_portals.ColourfulPortalsMod; +import quimufu.colourful_portals.portal_fluid.NullableAxis; +import quimufu.colourful_portals.portal_fluid.PortalFluid; + +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Map; + +import static quimufu.colourful_portals.ColourfulPortalsMod.LOGGER; + +public class CommonPortalFluidRendererV2 implements CommonPortalFluidRenderer { + + private Sprite sprite = null; + + private final float[] heights = new float[9]; + private final int[] heightsC = new int[9]; + + private static final EnumMap quaternions = + new EnumMap<>(Map.of( + NullableAxis.X, new Quaternionf() + .rotationTo(0,1,0,-1,0,0), + NullableAxis.Y, new Quaternionf(),//identity + NullableAxis.Z, new Quaternionf() + .rotationTo(0,1,0,0,0,-1), + NullableAxis.NULL, new Quaternionf()//identity + )); + + private final int[] amounts = new int[9]; + + private final float[] quads = new float[]{ + //Up + -0.5f, 0.5f, 0.0f, + 0.0f, 0.5f, 0.0f, + 0.0f, 0.5f, -0.5f, + -0.5f, 0.5f, -0.5f, + + 0.0f, 0.5f, 0.0f, + 0.5f, 0.5f, 0.0f, + 0.5f, 0.5f, -0.5f, + 0.0f, 0.5f, -0.5f, + + -0.5f, 0.5f, 0.5f, + 0.0f, 0.5f, 0.5f, + 0.0f, 0.5f, 0.0f, + -0.5f, 0.5f, 0.0f, + + 0.0f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.5f, 0.5f, 0.0f, + 0.0f, 0.5f, 0.0f, + + //Down + -0.5f, -0.5f, -0.5f, + 0.0f, -0.5f, -0.5f, + 0.0f, -0.5f, 0.0f, + -0.5f, -0.5f, 0.0f, + + 0.0f, -0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.5f, -0.5f, 0.0f, + 0.0f, -0.5f, 0.0f, + + -0.5f, -0.5f, 0.0f, + 0.0f, -0.5f, 0.0f, + 0.0f, -0.5f, 0.5f, + -0.5f, -0.5f, 0.5f, + + 0.0f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, 0.5f, + 0.0f, -0.5f, 0.5f, + + //NORTH + -0.5f, 0.5f, -0.5f, + 0.0f, 0.5f, -0.5f, + 0.0f, -0.5f, -0.5f, + -0.5f, -0.5f, -0.5f, + + 0.0f, 0.5f, -0.5f, + 0.5f, 0.5f, -0.5f, + 0.5f, -0.5f, -0.5f, + 0.0f, -0.5f, -0.5f, + + //SOUTH + -0.5f, -0.5f, 0.5f, + 0.0f, -0.5f, 0.5f, + 0.0f, 0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + + 0.0f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, 0.5f, 0.5f, + 0.0f, 0.5f, 0.5f, + + //WEST + -0.5f, -0.5f, -0.5f, + -0.5f, -0.5f, 0.0f, + -0.5f, 0.5f, 0.0f, + -0.5f, 0.5f, -0.5f, + + -0.5f, -0.5f, 0.0f, + -0.5f, -0.5f, 0.5f, + -0.5f, 0.5f, 0.5f, + -0.5f, 0.5f, 0.0f, + + //EAST + 0.5f, 0.5f, -0.5f, + 0.5f, 0.5f, 0.0f, + 0.5f, -0.5f, 0.0f, + 0.5f, -0.5f, -0.5f, + + 0.5f, 0.5f, 0.0f, + 0.5f, 0.5f, 0.5f, + 0.5f, -0.5f, 0.5f, + 0.5f, -0.5f, 0.0f, + }; + + public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos, Vector3f offset, VertexEater vertexEater) { + + FluidRenderHandler handler = FluidRenderHandlerRegistry.INSTANCE.get(fluidState.getFluid()); + sprite = handler.getFluidSprites(null, null, fluidState)[0]; + + NullableAxis axis = fluidState.get(PortalFluid.AXIS); + + int amount = fluidState.get(PortalFluid.AMOUNT); + if (amount == 0) + return false; + + //get neighbours heights: + saveAmounts(world, pos, axis); + + //offsets of corners: + Arrays.fill(heights, 0); + Arrays.fill(heightsC, 0); + for (int a = 0; a < 3; a++) { + for (int b = 0; b < 3; b++) { + if (amounts[a * 3 + b] <= -1) { + if ((a == 1) ^ (b == 1)) { + heights[a * 3 + b] += amounts[4] / 32f; + heightsC[a * 3 + b]++; + } + continue; + } + if (a < 2 && b < 2) { + heights[0] += amounts[a * 3 + b] / 32f; + heightsC[0]++; + } + if (a < 2 && b > 0) { + heights[2] += amounts[a * 3 + b] / 32f; + heightsC[2]++; + } + if (a > 0 && b < 2) { + heights[6] += amounts[a * 3 + b] / 32f; + heightsC[6]++; + } + if (a > 0 && b > 0) { + heights[8] += amounts[a * 3 + b] / 32f; + heightsC[8]++; + } + if ((a == 1) ^ (b == 1)) { + heights[a * 3 + b] += amounts[a * 3 + b] / 32f; + heights[a * 3 + b] += amounts[4] / 32f; //always != -1 + heightsC[a * 3 + b] += 2; + } + if ((a == 1) && (b == 1)) { + heights[4] = amounts[4] / 32f;//always != -1 + heightsC[4]++; + } + } + } + LOGGER.info("{} {} {}\n{} {} {}\n{} {} {}", amounts[0], amounts[1], amounts[2], amounts[3], amounts[4], amounts[5], amounts[6], amounts[7], amounts[8]); + + for (int a = 0; a < 9; a++) { + heights[a] = heights[a] / heightsC[a]; + } + LOGGER.info("{} {} {}\n{} {} {}\n{} {} {}", heights[0], heights[1], heights[2], heights[3], heights[4], heights[5], heights[6], heights[7], heights[8]); + for (int i = 0; i < quads.length / 3; i++) { + int x = (int) ((quads[i * 3] + 0.5f) * 2); + int z = (int) ((quads[i * 3 + 2] + 0.5f) * 2); + if (quads[i * 3 + 1] > 0f) { + quads[i * 3 + 1] = 0f + heights[x * 3 + z]; + } else { + quads[i * 3 + 1] = 0f - heights[x * 3 + z]; + } + } + vertexEater.setSprite(sprite); + int endUp = 4; + int endDown = 8; + int endNorth = 10; + int endSouth = 12; + int endWest = 14; + int endEast = 16; + for (Direction value : Direction.values()) { + switch (value) { + case UP -> { + for (int i = 0; i < endUp; i++) { + for (int j = 0; j < 4; j++) { + + vertexEater.eatVertex( + quads[i * 12 + j * 3], + quads[i * 12 + j * 3 + 1], + quads[i * 12 + j * 3 + 2], + sprite.getFrameU(quads[i * 12 + j * 3] + 0.5f), + sprite.getFrameV(quads[i * 12 + j * 3 + 2] + 0.5f)); + } + vertexEater.drawQuad(offset, quaternions.get(axis), Direction.UP); + } + } + case DOWN -> { + for (int i = endUp; i < endDown; i++) { + for (int j = 0; j < 4; j++) { + vertexEater.eatVertex( + quads[i * 12 + j * 3], + quads[i * 12 + j * 3 + 1], + quads[i * 12 + j * 3 + 2], + sprite.getFrameU(quads[i * 12 + j * 3] + 0.5f), + sprite.getFrameV(quads[i * 12 + j * 3 + 2] + 0.5f)); + } + vertexEater.drawQuad(offset, quaternions.get(axis), Direction.DOWN); + } + } + case NORTH -> { + if (amounts[3] >= -1) { + continue; + } + for (int i = endDown; i < endNorth; i++) { + for (int j = 0; j < 4; j++) { + vertexEater.eatVertex( + quads[i * 12 + j * 3], + quads[i * 12 + j * 3 + 1], + quads[i * 12 + j * 3 + 2], + sprite.getFrameU(quads[i * 12 + j * 3] + 0.5f), + sprite.getFrameV(quads[i * 12 + j * 3 + 1] + 0.5f)); + } + vertexEater.drawQuad(offset, quaternions.get(axis), Direction.NORTH); + } + } + case SOUTH -> { + if (amounts[5] >= -1) { + continue; + } + for (int i = endNorth; i < endSouth; i++) { + for (int j = 0; j < 4; j++) { + vertexEater.eatVertex( + quads[i * 12 + j * 3], + quads[i * 12 + j * 3 + 1], + quads[i * 12 + j * 3 + 2], + sprite.getFrameU(quads[i * 12 + j * 3] + 0.5f), + sprite.getFrameV(quads[i * 12 + j * 3 + 1] + 0.5f)); + } + vertexEater.drawQuad(offset, quaternions.get(axis), Direction.SOUTH); + } + } + case WEST -> { + if (amounts[1] >= -1) { + continue; + } + for (int i = endSouth; i < endWest; i++) { + for (int j = 0; j < 4; j++) { + vertexEater.eatVertex( + quads[i * 12 + j * 3], + quads[i * 12 + j * 3 + 1], + quads[i * 12 + j * 3 + 2], + sprite.getFrameU(quads[i * 12 + j * 3 + 1] + 0.5f), + sprite.getFrameV(quads[i * 12 + j * 3 + 2] + 0.5f)); + } + vertexEater.drawQuad(offset, quaternions.get(axis), Direction.WEST); + } + } + case EAST -> { + if (amounts[7] >= -1) { + continue; + } + for (int i = endWest; i < endEast; i++) { + for (int j = 0; j < 4; j++) { + vertexEater.eatVertex( + quads[i * 12 + j * 3], + quads[i * 12 + j * 3 + 1], + quads[i * 12 + j * 3 + 2], + sprite.getFrameU(quads[i * 12 + j * 3 + 1] + 0.5f), + sprite.getFrameV(quads[i * 12 + j * 3 + 2] + 0.5f)); + } + vertexEater.drawQuad(offset, quaternions.get(axis), Direction.EAST); + } + } + } + } + return true; + } + + private void saveAmounts(BlockRenderView world, BlockPos pos, NullableAxis axis) { + BlockPos.Mutable curr = new BlockPos.Mutable(); + switch (axis) { + case NULL -> { + Arrays.fill(amounts, -2); + amounts[4] = 16; + } + case X -> { + for (int y = 0; y < 3; y++) { + for (int z = 0; z < 3; z++) { + saveAmount(world, pos, curr, 0, y - 1, z - 1, y, z); + } + } + } + case Y -> { + for (int x = 0; x < 3; x++) { + for (int z = 0; z < 3; z++) { + saveAmount(world, pos, curr, x - 1, 0, z - 1, x, z); + } + } + } + case Z -> { + for (int x = 0; x < 3; x++) { + for (int y = 0; y < 3; y++) { + saveAmount(world, pos, curr, x - 1, y - 1, 0, x, y); + } + } + } + } + } + + private void saveAmount(BlockRenderView world, BlockPos pos, BlockPos.Mutable curr, int dx, int dy, int dz, int major, int minor) { + curr.set(pos); + curr.move(dx, dy, dz); + BlockState blockState = world.getBlockState(curr); + FluidState fluidState = blockState + .getFluidState(); + if (fluidState.isOf(ColourfulPortalsMod.PORTAL_FLUID)) { + amounts[major * 3 + minor] = fluidState.get(PortalFluid.AMOUNT); + } else { + Direction direction = Direction.fromVector(dx, dy, dz); + if (direction != null && blockState.isSideSolidFullSquare(world, curr, direction.getOpposite())) { + amounts[major * 3 + minor] = -1; + } else { + amounts[major * 3 + minor] = -2; + } + } + } + +} diff --git a/src/main/java/quimufu/colourful_portals/client/PortalFluidRenderHandler.java b/src/main/java/quimufu/colourful_portals/client/PortalFluidRenderHandler.java index 6c62d09..7923037 100644 --- a/src/main/java/quimufu/colourful_portals/client/PortalFluidRenderHandler.java +++ b/src/main/java/quimufu/colourful_portals/client/PortalFluidRenderHandler.java @@ -13,18 +13,21 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.BlockRenderView; import org.jetbrains.annotations.Nullable; +import org.joml.Quaternionf; +import org.joml.Vector3f; import quimufu.colourful_portals.ColourfulPortalsMod; +import quimufu.colourful_portals.ColourfulPortalsModClient; @Environment(value = EnvType.CLIENT) -public class PortalFluidRenderHandler implements FluidRenderHandler, CommonPortalFluidRenderer.VertexEater { +public class PortalFluidRenderHandler implements FluidRenderHandler, VertexEater { Identifier PORTAL_FLUID_STILL = Identifier.of(ColourfulPortalsMod.MOD_ID, "block/portal_still"); - private final CommonPortalFluidRenderer commonPortalFluidRenderer = new CommonPortalFluidRenderer(); private Sprite sprite = null; private final ThreadLocal vertexConsumer = new ThreadLocal<>(); private final ThreadLocal i = new ThreadLocal<>(); private final ThreadLocal vertices = new ThreadLocal<>(); + private final ThreadLocal tmpVector = ThreadLocal.withInitial(Vector3f::new); @Override public Sprite[] getFluidSprites(@Nullable BlockRenderView view, @Nullable BlockPos pos, FluidState state) { @@ -39,11 +42,13 @@ public class PortalFluidRenderHandler implements FluidRenderHandler, CommonPorta @Override public void renderFluid(BlockPos pos, BlockRenderView world, VertexConsumer vertexConsumer, BlockState blockState, FluidState fluidState) { this.vertexConsumer.set(vertexConsumer); - BlockPos offset = new BlockPos(pos.getX() & 0xF, pos.getY() & 0xF, pos.getZ() & 0xF); + Vector3f offset = new Vector3f(pos.getX() & 0xF, pos.getY() & 0xF, pos.getZ() & 0xF); + offset.add(0.5f,0.5f,0.5f); if (vertices.get() == null) { vertices.set(new float[4][5]); } - commonPortalFluidRenderer.render(world, fluidState, pos, offset, this); + ColourfulPortalsModClient.FLUID_RENDERER.get() + .render(world, fluidState, pos, offset, this); } @@ -71,14 +76,16 @@ public class PortalFluidRenderHandler implements FluidRenderHandler, CommonPorta } @Override - public void drawQuad(BlockPos offset, Direction direction) { - float offX = offset.getX(); - float offY = offset.getY(); - float offZ = offset.getZ(); + public void drawQuad(Vector3f offset, Quaternionf rotation, Direction direction) { + float offX = offset.x; + float offY = offset.y; + float offZ = offset.z; + Vector3f f = tmpVector.get(); for (float[] v : vertices.get()) { - + f.set(v); + rotation.transform(f); vertexConsumer.get() - .vertex(offX + v[0], offY + v[1], offZ + v[2]) + .vertex(offX + f.x, offY + f.y, offZ + f.z) .color(1f, 1f, 1f, 1.0f) .texture(v[3], v[4]) .light(16) diff --git a/src/main/java/quimufu/colourful_portals/client/SodiumPortalFluidRenderHandler.java b/src/main/java/quimufu/colourful_portals/client/SodiumPortalFluidRenderHandler.java index e466595..a1a3c45 100644 --- a/src/main/java/quimufu/colourful_portals/client/SodiumPortalFluidRenderHandler.java +++ b/src/main/java/quimufu/colourful_portals/client/SodiumPortalFluidRenderHandler.java @@ -4,14 +4,11 @@ import me.jellysquid.mods.sodium.client.model.quad.ModelQuad; import me.jellysquid.mods.sodium.client.model.quad.ModelQuadView; import me.jellysquid.mods.sodium.client.model.quad.ModelQuadViewMutable; import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadFacing; -import me.jellysquid.mods.sodium.client.model.quad.properties.ModelQuadWinding; import me.jellysquid.mods.sodium.client.render.chunk.compile.ChunkBuildBuffers; import me.jellysquid.mods.sodium.client.render.chunk.compile.buffers.ChunkModelBuilder; import me.jellysquid.mods.sodium.client.render.chunk.terrain.material.DefaultMaterials; import me.jellysquid.mods.sodium.client.render.chunk.terrain.material.Material; -import me.jellysquid.mods.sodium.client.render.chunk.vertex.builder.ChunkMeshBufferBuilder; import me.jellysquid.mods.sodium.client.render.chunk.vertex.format.ChunkVertexEncoder; -import me.jellysquid.mods.sodium.client.render.chunk.vertex.format.ChunkVertexEncoder.Vertex; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.texture.Sprite; @@ -19,14 +16,18 @@ import net.minecraft.fluid.FluidState; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.world.BlockRenderView; +import org.joml.Quaternionf; +import org.joml.Vector3f; +import quimufu.colourful_portals.ColourfulPortalsMod; +import quimufu.colourful_portals.ColourfulPortalsModClient; @Environment(value = EnvType.CLIENT) -public class SodiumPortalFluidRenderHandler implements CommonPortalFluidRenderer.VertexEater { +public class SodiumPortalFluidRenderHandler implements VertexEater { private Sprite sprite = null; private final ModelQuadViewMutable quad = new ModelQuad(); - private final CommonPortalFluidRenderer commonPortalFluidRenderer = new CommonPortalFluidRenderer(); + private final CommonPortalFluidRenderer commonPortalFluidRenderer = ColourfulPortalsModClient.FLUID_RENDERER.get(); private final ChunkVertexEncoder.Vertex[] vertices = ChunkVertexEncoder.Vertex.uninitializedQuad(); private int i; private ChunkModelBuilder chunkModelBuilder; @@ -38,7 +39,9 @@ public class SodiumPortalFluidRenderHandler implements CommonPortalFluidRenderer public boolean render(BlockRenderView world, FluidState fluidState, BlockPos pos, BlockPos offset, ChunkBuildBuffers buffers) { material = DefaultMaterials.forFluidState(fluidState); this.chunkModelBuilder = buffers.get(material); - return commonPortalFluidRenderer.render(world,fluidState,pos,offset,this); + Vector3f vOffset = new Vector3f(offset.getX(), offset.getY(), offset.getZ()); + vOffset.add(0.5f,0.5f,0.5f); + return commonPortalFluidRenderer.render(world,fluidState,pos, vOffset,this); } @@ -59,18 +62,18 @@ public class SodiumPortalFluidRenderHandler implements CommonPortalFluidRenderer } @Override - public void drawQuad(BlockPos offset, Direction direction) { + public void drawQuad(Vector3f offset, Quaternionf rot, Direction direction) { writeQuad(chunkModelBuilder, material, offset, quad, ModelQuadFacing.fromDirection(direction), false); } - private void writeQuad(ChunkModelBuilder builder, Material material, BlockPos offset, ModelQuadView quad, ModelQuadFacing facing, boolean flip) { + private void writeQuad(ChunkModelBuilder builder, Material material, Vector3f offset, ModelQuadView quad, ModelQuadFacing facing, boolean flip) { var vertices = this.vertices; for (int i = 0; i < 4; i++) { var out = vertices[flip ? 3 - i : i]; - out.x = offset.getX() + quad.getX(i); - out.y = offset.getY() + quad.getY(i); - out.z = offset.getZ() + quad.getZ(i); + out.x = offset.x + quad.getX(i); + out.y = offset.y + quad.getY(i); + out.z = offset.z + quad.getZ(i); out.color = 0xFFFFFFFF; out.u = quad.getTexU(i); out.v = quad.getTexV(i); diff --git a/src/main/java/quimufu/colourful_portals/client/VertexEater.java b/src/main/java/quimufu/colourful_portals/client/VertexEater.java new file mode 100644 index 0000000..b7c5fb8 --- /dev/null +++ b/src/main/java/quimufu/colourful_portals/client/VertexEater.java @@ -0,0 +1,15 @@ +package quimufu.colourful_portals.client; + +import net.minecraft.client.texture.Sprite; +import net.minecraft.util.math.Direction; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +public interface VertexEater { + + void setSprite(Sprite sprite); + + void eatVertex(float x, float y, float z, float frameU, float frameV); + + void drawQuad(Vector3f offset, Quaternionf quaternionf, Direction direction); +} diff --git a/src/main/java/quimufu/colourful_portals/config/ColourfulPortalConfig.java b/src/main/java/quimufu/colourful_portals/config/ColourfulPortalConfig.java index 6e04ac1..5d39a14 100644 --- a/src/main/java/quimufu/colourful_portals/config/ColourfulPortalConfig.java +++ b/src/main/java/quimufu/colourful_portals/config/ColourfulPortalConfig.java @@ -2,8 +2,12 @@ package quimufu.colourful_portals.config; import com.google.common.collect.Lists; import eu.midnightdust.lib.config.MidnightConfig; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; import net.minecraft.util.DyeColor; +import quimufu.colourful_portals.util.Procedure; +import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -64,10 +68,14 @@ public class ColourfulPortalConfig extends MidnightConfig { @Entry(category = "text", name = "Blocks that create black portals") public static List black = Lists.newArrayList("minecraft:black_wool"); - //todo: disabled until i find a good solution - //@Entry(category = "text", name = "Blocks that create fully transparent portals") + @Entry(category = "text", name = "Blocks that create fully transparent portals") public static List none = Lists.newArrayList(); + @Entry(category = "text", name = "Use the old Portal Fluid look") + public static boolean blockyPortalFluid = false; + + private static final ArrayList onWrite = new ArrayList<>(2); + public static Set getAllPortalBlocks() { Set allBlocks = new HashSet<>(); allBlocks.addAll(white); @@ -129,4 +137,17 @@ public class ColourfulPortalConfig extends MidnightConfig { throw new IllegalArgumentException("Invalid portal block: " + block); } } + + @Override + public void writeChanges(String modid) { + super.writeChanges(modid); + for (Procedure procedure : onWrite) { + procedure.run(); + } + + } + + public static void registerListener(Procedure p) { + onWrite.add(p); + } } diff --git a/src/main/java/quimufu/colourful_portals/mixin/client/SodiumFluidRendererMixin.java b/src/main/java/quimufu/colourful_portals/mixin/client/SodiumFluidRendererMixin.java index f9fb87f..719c8ce 100644 --- a/src/main/java/quimufu/colourful_portals/mixin/client/SodiumFluidRendererMixin.java +++ b/src/main/java/quimufu/colourful_portals/mixin/client/SodiumFluidRendererMixin.java @@ -6,6 +6,7 @@ import me.jellysquid.mods.sodium.client.world.WorldSlice; import net.minecraft.fluid.FluidState; import net.minecraft.util.math.BlockPos; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @@ -16,12 +17,13 @@ import static quimufu.colourful_portals.ColourfulPortalsMod.PORTAL_FLUID; @Mixin(FluidRenderer.class) public class SodiumFluidRendererMixin { - private final SodiumPortalFluidRenderHandler sodiumPortalFluidRenderHandler = new SodiumPortalFluidRenderHandler(); + @Unique + private final ThreadLocal sodiumPortalFluidRenderHandler = ThreadLocal.withInitial(SodiumPortalFluidRenderHandler::new); @Inject(at = @At("HEAD"), method = "render", cancellable = true, remap = false) private void init(WorldSlice world, FluidState fluidState, BlockPos blockPos, BlockPos offset, ChunkBuildBuffers buffers, CallbackInfo ci) { if (fluidState.isOf(PORTAL_FLUID)) { - sodiumPortalFluidRenderHandler.render(world, fluidState, blockPos, offset, buffers); + sodiumPortalFluidRenderHandler.get().render(world, fluidState, blockPos, offset, buffers); ci.cancel(); } } diff --git a/src/main/java/quimufu/colourful_portals/portal_fluid/NullableAxis.java b/src/main/java/quimufu/colourful_portals/portal_fluid/NullableAxis.java index fdedce8..0aa6c2f 100644 --- a/src/main/java/quimufu/colourful_portals/portal_fluid/NullableAxis.java +++ b/src/main/java/quimufu/colourful_portals/portal_fluid/NullableAxis.java @@ -13,7 +13,6 @@ public enum NullableAxis implements StringIdentifiable { private final Direction.Axis axis; NullableAxis(Direction.Axis axis) { - this.axis = axis; } diff --git a/src/main/java/quimufu/colourful_portals/util/Procedure.java b/src/main/java/quimufu/colourful_portals/util/Procedure.java new file mode 100644 index 0000000..81eb031 --- /dev/null +++ b/src/main/java/quimufu/colourful_portals/util/Procedure.java @@ -0,0 +1,20 @@ +package quimufu.colourful_portals.util; + +@FunctionalInterface +public interface Procedure { + void run(); + + default Procedure andThen(Procedure after){ + return () -> { + this.run(); + after.run(); + }; + } + + default Procedure compose(Procedure before){ + return () -> { + before.run(); + this.run(); + }; + } +} \ No newline at end of file