diff --git a/src/main/java/name/synchro/blockModels/UnbakedSlopeModel.java b/src/main/java/name/synchro/blockModels/UnbakedSlopeModel.java index 5553ec8..91f2d18 100644 --- a/src/main/java/name/synchro/blockModels/UnbakedSlopeModel.java +++ b/src/main/java/name/synchro/blockModels/UnbakedSlopeModel.java @@ -30,7 +30,6 @@ @Environment(EnvType.CLIENT) public class UnbakedSlopeModel implements UnbakedModel { private final SlopeShape slopeShape; - private Mesh mesh; private Sprite sprite; private final SpriteIdentifier spriteID; private static final Vector3f CENTERED_VECTOR = new Vector3f(0.5f, 0.5f, 0.5f); @@ -67,7 +66,7 @@ public BakedModel bake(Baker baker, Function textureGe case INNER -> emitInnerSlope(builder, transformation); case OUTER -> emitOuterSlope(builder, transformation); } - mesh = builder.build(); + Mesh mesh = builder.build(); return new BakedSlopeModel(mesh, sprite); } @@ -77,27 +76,27 @@ private void emitNormalSlope(MeshBuilder builder, AffineTransformation transform new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 1f, 0f)}); + new Vector3f(1f, 1f, 0f)}); // slope side addSimpleQuad(emitter, Direction.NORTH, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 0f), - new Vector3f(1f, 0f, 0f), + new Vector3f(0.5f, 0.5f, 0f), new Vector3f(1f, 1f, 0f), - new Vector3f(1f, 0f, 0f)}); + new Vector3f(1f, 0f, 0f)}); // triangle addSimpleQuad(emitter, Direction.SOUTH, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 1f), new Vector3f(1f, 0f, 1f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 0f, 1f)}); + new Vector3f(0.5f, 0.5f, 1f)}); // triangle addSimpleQuad(emitter, Direction.EAST, transformation, new Vector3f[]{ new Vector3f(1f, 0f, 0f), new Vector3f(1f, 1f, 0f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 0f, 1f)}); + new Vector3f(1f, 0f, 1f)}); // full addSimpleQuad(emitter, Direction.DOWN, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 0f), new Vector3f(1f, 0f, 0f), new Vector3f(1f, 0f, 1f), - new Vector3f(0f, 0f, 1f)}); + new Vector3f(0f, 0f, 1f)}); // full } private void emitOuterSlope (MeshBuilder builder, AffineTransformation transformation){ @@ -106,27 +105,27 @@ private void emitOuterSlope (MeshBuilder builder, AffineTransformation transform new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 0f, 1f)}); + new Vector3f(0.5f, 0.5f, 0.5f)}); // half slope addSimpleQuad(emitter, Direction.NORTH, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 0f), - new Vector3f(1f, 0f, 1f), + new Vector3f(0.5f, 0.5f, 0.5f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 0f, 0f)}); + new Vector3f(1f, 0f, 0f)}); // half slope addSimpleQuad(emitter, Direction.EAST, transformation, new Vector3f[]{ new Vector3f(1f, 0f, 0f), - new Vector3f(1f, 0f, 1f), + new Vector3f(1f, 0.5f, 0.5f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 0f, 1f)}); + new Vector3f(1f, 0f, 1f)}); // triangle addSimpleQuad(emitter, Direction.SOUTH, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 1f), new Vector3f(1f, 0f, 1f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 0f, 1f)}); + new Vector3f(0.5f, 0.5f, 1f)}); // triangle addSimpleQuad(emitter, Direction.DOWN, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 0f), new Vector3f(1f, 0f, 0f), new Vector3f(1f, 0f, 1f), - new Vector3f(0f, 0f, 1f)}); + new Vector3f(0f, 0f, 1f)}); // full } private void emitInnerSlope (MeshBuilder builder, AffineTransformation transformation){ @@ -135,48 +134,47 @@ private void emitInnerSlope (MeshBuilder builder, AffineTransformation transform new Vector3f(0f, 0f, 0f), new Vector3f(0f, 1f, 1f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 0f, 0f)}); + new Vector3f(1f, 0f, 0f)}); // slope addSimpleQuad(emitter, Direction.WEST, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 1f, 0f)}); + new Vector3f(1f, 1f, 0f)}); // slope addSimpleQuad(emitter, Direction.NORTH, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 0f), - new Vector3f(1f, 0f, 0f), + new Vector3f(0.5f, 0.5f, 0f), new Vector3f(1f, 1f, 0f), - new Vector3f(1f, 0f, 0f)}); + new Vector3f(1f, 0f, 0f)}); // triangle addSimpleQuad(emitter, Direction.WEST, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 0f), new Vector3f(0f, 0f, 1f), new Vector3f(0f, 1f, 1f), - new Vector3f(0f, 0f, 1f)}); + new Vector3f(0f, 0.5f, 0.5f)}); // triangle addSimpleQuad(emitter, Direction.EAST, transformation, new Vector3f[]{ new Vector3f(1f, 0f, 0f), new Vector3f(1f, 1f, 0f), new Vector3f(1f, 1f, 1f), - new Vector3f(1f, 0f, 1f)}); + new Vector3f(1f, 0f, 1f)}); // full addSimpleQuad(emitter, Direction.SOUTH, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 1f), new Vector3f(1f, 0f, 1f), new Vector3f(1f, 1f, 1f), - new Vector3f(0f, 1f, 1f)}); + new Vector3f(0f, 1f, 1f)}); // full addSimpleQuad(emitter, Direction.DOWN, transformation, new Vector3f[]{ new Vector3f(0f, 0f, 0f), new Vector3f(1f, 0f, 0f), new Vector3f(1f, 0f, 1f), - new Vector3f(0f, 0f, 1f)}); + new Vector3f(0f, 0f, 1f)}); // full } - private QuadEmitter addSimpleQuad(QuadEmitter emitter, Direction direction, AffineTransformation transformation, Vector3f[] vertexes){ - emitter.nominalFace(Direction.transform(transformation.getMatrix(), direction)); + private void addSimpleQuad(QuadEmitter emitter, Direction direction, AffineTransformation transformation, Vector3f[] vertexes){ + emitter.cullFace(Direction.transform(transformation.getMatrix(), direction)); for (int index = 0; index < 4; ++index){ emitter.pos(index, transformVertex(vertexes[index], transformation.getMatrix()) ); } emitter.spriteBake(sprite, MutableQuadView.BAKE_LOCK_UV); emitter.color(-1, -1, -1, -1); emitter.emit(); - return emitter; } private Vector3f transformVertex(Vector3f vertex, Matrix4f transformationMatrix) { diff --git a/src/main/java/name/synchro/fluids/gases/DebugGasRenderHandler.java b/src/main/java/name/synchro/fluids/gases/DebugGasRenderHandler.java new file mode 100644 index 0000000..1e868cf --- /dev/null +++ b/src/main/java/name/synchro/fluids/gases/DebugGasRenderHandler.java @@ -0,0 +1,18 @@ +package name.synchro.fluids.gases; + +import net.minecraft.client.render.VertexConsumer; + +@Deprecated +public class DebugGasRenderHandler extends TranslucentGasRenderer { + public DebugGasRenderHandler(Gas gas) { + super(gas); + } + + @Override + protected void vertex(VertexConsumer vertexConsumer, double[] xyz0, double[] xyz, float[] rgba, float[] uv, int light) { + double x = xyz0[0] + xyz[0]; + double y = xyz0[1] + xyz[1]; + double z = xyz0[2] + xyz[2]; + vertexConsumer.vertex(x, y, z).color(rgba[0], rgba[1], rgba[2], 0.85f).texture(uv[0], uv[1]).light(light).normal(0.0F, 1.0F, 0.0F).next(); + } +} diff --git a/src/main/java/name/synchro/fluids/gases/Gas.java b/src/main/java/name/synchro/fluids/gases/Gas.java index 526aa92..09ee9e8 100644 --- a/src/main/java/name/synchro/fluids/gases/Gas.java +++ b/src/main/java/name/synchro/fluids/gases/Gas.java @@ -32,12 +32,12 @@ public abstract class Gas extends Fluid { public final int volatilizationRate; public final int color; - public final Vector3f colorVector; + public final Vector3f rgb; protected final DustParticleEffect gasParticleEffect; public Gas(int color, int upsideMinGradient, int downsideMinGradient, int horizontalMinGradient, int volatilizationRate) { this.color = color; - this.colorVector = new Vector3f((color >> 16 & 0xff) / 255f, (color >> 8 & 0xff) / 255f, (color & 0xff) / 255f); - this.gasParticleEffect = new DustParticleEffect(colorVector, 0.5f); + this.rgb = new Vector3f((color >> 16 & 0xff) / 255f, (color >> 8 & 0xff) / 255f, (color & 0xff) / 255f); + this.gasParticleEffect = new DustParticleEffect(rgb, 0.5f); this.upsideMinGradient = Math.max(upsideMinGradient, 2) ; this.downsideMinGradient = Math.max(downsideMinGradient, 2); this.horizontalMinGradient = Math.max(horizontalMinGradient, 2); diff --git a/src/main/java/name/synchro/fluids/gases/TranslucentGasRenderHandler.java b/src/main/java/name/synchro/fluids/gases/TranslucentGasRenderHandler.java deleted file mode 100644 index f8ec242..0000000 --- a/src/main/java/name/synchro/fluids/gases/TranslucentGasRenderHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package name.synchro.fluids.gases; - -import name.synchro.Synchro; -import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; -import net.minecraft.client.texture.Sprite; -import net.minecraft.client.texture.SpriteAtlasTexture; -import net.minecraft.fluid.FluidState; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.BlockRenderView; -import org.jetbrains.annotations.Nullable; - -public class TranslucentGasRenderHandler implements FluidRenderHandler { - protected final Identifier[] textures; - protected final Identifier emptyTexture; - protected final Sprite[][] spritesList; - protected final int tint; - public TranslucentGasRenderHandler(int tint) { - this.textures = new Identifier[8]; - this.emptyTexture = new Identifier(Synchro.MOD_ID, "block/gas/invisible_gas"); - this.spritesList = new Sprite[8][3]; - this.tint = tint; - } - - public TranslucentGasRenderHandler(Gas gas){ - this(gas.color); - } - - @Override - public Sprite[] getFluidSprites(@Nullable BlockRenderView view, @Nullable BlockPos pos, FluidState state) { - return spritesList[(state.getLevel() - 1) / 2]; - } - - @Override - public int getFluidColor(@Nullable BlockRenderView view, @Nullable BlockPos pos, FluidState state) { - return tint; - } - - @Override - public void reloadTextures(SpriteAtlasTexture textureAtlas) { - textures[0] = new Identifier(Synchro.MOD_ID,"block/gas/visible_gas_opaqueness_0"); - textures[1] = new Identifier(Synchro.MOD_ID,"block/gas/visible_gas_opaqueness_1"); - textures[2] = new Identifier(Synchro.MOD_ID,"block/gas/visible_gas_opaqueness_2"); - textures[3] = new Identifier(Synchro.MOD_ID,"block/gas/visible_gas_opaqueness_3"); - textures[4] = new Identifier(Synchro.MOD_ID,"block/gas/visible_gas_opaqueness_4"); - textures[5] = new Identifier(Synchro.MOD_ID,"block/gas/visible_gas_opaqueness_5"); - textures[6] = new Identifier(Synchro.MOD_ID,"block/gas/visible_gas_opaqueness_6"); - textures[7] = new Identifier(Synchro.MOD_ID,"block/gas/visible_gas_opaqueness_7"); - for (int i = 0; i < 8; ++i){ - spritesList[i][0] = textureAtlas.getSprite(textures[i]); - spritesList[i][1] = textureAtlas.getSprite(textures[i]); - spritesList[i][2] = textureAtlas.getSprite(textures[i]); - } - } -} diff --git a/src/main/java/name/synchro/fluids/gases/TranslucentGasRenderer.java b/src/main/java/name/synchro/fluids/gases/TranslucentGasRenderer.java new file mode 100644 index 0000000..54e9c51 --- /dev/null +++ b/src/main/java/name/synchro/fluids/gases/TranslucentGasRenderer.java @@ -0,0 +1,127 @@ +package name.synchro.fluids.gases; + +import name.synchro.Synchro; +import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; +import net.minecraft.block.BlockState; +import net.minecraft.client.render.LightmapTextureManager; +import net.minecraft.client.render.VertexConsumer; +import net.minecraft.client.render.WorldRenderer; +import net.minecraft.client.texture.Sprite; +import net.minecraft.client.texture.SpriteAtlasTexture; +import net.minecraft.fluid.FluidState; +import net.minecraft.util.Identifier; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.shape.VoxelShape; +import net.minecraft.util.shape.VoxelShapes; +import net.minecraft.world.BlockRenderView; +import net.minecraft.world.BlockView; +import org.jetbrains.annotations.Nullable; + +public class TranslucentGasRenderer implements FluidRenderHandler { + public static final Identifier GAS_TEXTURE_ID = new Identifier(Synchro.MOD_ID, "block/gas"); + protected final Identifier[] textures; + protected final Sprite[] spritesList; + protected final Gas gas; + + public TranslucentGasRenderer(Gas gas) { + this.textures = new Identifier[2]; + this.textures[0] = GAS_TEXTURE_ID; + this.textures[1] = textures[0]; + this.spritesList = new Sprite[2]; + this.gas = gas; + } + + @Override + public Sprite[] getFluidSprites(@Nullable BlockRenderView view, @Nullable BlockPos pos, FluidState state) { + return this.spritesList; + } + + @Override + public int getFluidColor(@Nullable BlockRenderView view, @Nullable BlockPos pos, FluidState state) { + return this.gas.color; + } + + @Override + public void reloadTextures(SpriteAtlasTexture textureAtlas) { + spritesList[0] = textureAtlas.getSprite(textures[0]); + spritesList[1] = textureAtlas.getSprite(textures[1]); + } + + @Override + public void renderFluid(BlockPos pos, BlockRenderView world, VertexConsumer vertexConsumer, BlockState blockState, FluidState fluidState) { + boolean u = shouldRenderFace(world, pos, Direction.UP); + boolean d = shouldRenderFace(world, pos, Direction.DOWN); + boolean w = shouldRenderFace(world, pos, Direction.WEST); + boolean s = shouldRenderFace(world, pos, Direction.SOUTH); + boolean e = shouldRenderFace(world, pos, Direction.EAST); + boolean n = shouldRenderFace(world, pos, Direction.NORTH); + if (!(u || d || w || s || e || n)) return; + double x0 = pos.getX() & 15; + double y0 = pos.getY() & 15; + double z0 = pos.getZ() & 15; + double[] xyz0 = {x0, y0, z0}; + float u0 = spritesList[0].getMinU(); + float u1 = spritesList[0].getMaxU(); + float v0 = spritesList[0].getMinV(); + float v1 = spritesList[0].getMaxV(); + float[] u0v0u1v1 = {u0, v0, u1, v1}; + float[] rgba = {this.gas.rgb.x, this.gas.rgb.y, this.gas.rgb.z, 0.5f * fluidState.getLevel() / 16f}; + int light = getLight(world, pos); + if (u) vertexQuad(vertexConsumer, xyz0, 0x7326, rgba, u0v0u1v1, light); + if (d) vertexQuad(vertexConsumer, xyz0, 0x5401, rgba, u0v0u1v1, light); + if (w) vertexQuad(vertexConsumer, xyz0, 0x2046, rgba, u0v0u1v1, light); + if (s) vertexQuad(vertexConsumer, xyz0, 0x6457, rgba, u0v0u1v1, light); + if (e) vertexQuad(vertexConsumer, xyz0, 0x7513, rgba, u0v0u1v1, light); + if (n) vertexQuad(vertexConsumer, xyz0, 0x3102, rgba, u0v0u1v1, light); + } + + protected void vertex(VertexConsumer vertexConsumer, double[] xyz0, double[] xyz, float[] rgba, float[] uv, int light) { + double x = xyz0[0] + xyz[0]; + double y = xyz0[1] + xyz[1]; + double z = xyz0[2] + xyz[2]; + vertexConsumer.vertex(x, y, z).color(rgba[0], rgba[1], rgba[2], rgba[3]).texture(uv[0], uv[1]).light(light).normal(0.0F, 1.0F, 0.0F).next(); + } + + private void vertexQuad(VertexConsumer vertexConsumer, double[] xyz0, int array, float[] rgba, float[] u0v0u1v1, int light) { + final int[] uvs = {0, 2, 3, 1}; + for (int i = 0; i < 4; i++) { + int n = (array >>> ((3 - i) << 2)) & 0b1111; + double[] xyz = {n & 1, (n >>> 1) & 1, (n >>> 2 ) & 1}; + int m = uvs[i]; + float[] uv = {(m & 1) == 0 ? u0v0u1v1[0] : u0v0u1v1[2] , ((m & 2) >>> 1) == 0 ? u0v0u1v1[1]: u0v0u1v1[3]}; + vertex(vertexConsumer, xyz0, xyz, rgba, uv, light); + } + } + + private static boolean shouldRenderFace(BlockRenderView view, BlockPos pos, Direction direction){ + BlockState blockState = view.getBlockState(pos.offset(direction)); + FluidState fluidState = view.getFluidState(pos.offset(direction)); + if (fluidState.getFluid() instanceof Gas) return false; + return !isSideCovered(view, direction, pos.offset(direction), blockState); + } + + private static boolean isSideCovered(BlockView world, Direction direction, BlockPos pos, BlockState state) { + if (state.isOpaque()) { + VoxelShape voxelShape = VoxelShapes.empty(); + VoxelShape voxelShape2 = state.getCullingShape(world, pos); + return VoxelShapes.isSideCovered(voxelShape, voxelShape2, direction); + } else { + return false; + } + } + + /** + * From Vanilla + */ + private static int getLight(BlockRenderView world, BlockPos pos) { + int i = WorldRenderer.getLightmapCoordinates(world, pos); + int j = WorldRenderer.getLightmapCoordinates(world, pos.up()); + int k = i & (LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE | 15); + int l = j & (LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE | 15); + int m = i >> 16 & (LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE | 15); + int n = j >> 16 & (LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE | 15); + return (Math.max(k, l)) | (Math.max(m, n)) << 16; + } + +} diff --git a/src/main/java/name/synchro/mixin/FluidConcerned/FluidRendererMixin.java b/src/main/java/name/synchro/mixin/FluidConcerned/FluidRendererMixin.java index b19809c..f7f7282 100644 --- a/src/main/java/name/synchro/mixin/FluidConcerned/FluidRendererMixin.java +++ b/src/main/java/name/synchro/mixin/FluidConcerned/FluidRendererMixin.java @@ -12,7 +12,7 @@ import org.spongepowered.asm.mixin.injection.At; @Mixin(FluidRenderer.class) -public class FluidRendererMixin { +public abstract class FluidRendererMixin { @WrapOperation(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/block/BlockState;getFluidState()Lnet/minecraft/fluid/FluidState;", ordinal = 0)) private FluidState getFluidStateDown(BlockState instance, Operation original, diff --git a/src/main/java/name/synchro/registrations/FluidRenderers.java b/src/main/java/name/synchro/registrations/FluidRenderers.java index cbdc8ce..d2db51a 100644 --- a/src/main/java/name/synchro/registrations/FluidRenderers.java +++ b/src/main/java/name/synchro/registrations/FluidRenderers.java @@ -1,18 +1,19 @@ package name.synchro.registrations; import name.synchro.Synchro; -import name.synchro.fluids.gases.TranslucentGasRenderHandler; +import name.synchro.fluids.gases.DebugGasRenderHandler; import name.synchro.fluids.gases.TransparentGasRenderHandler; +import name.synchro.fluids.gases.TranslucentGasRenderer; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; public final class FluidRenderers { public static void registerAll() { - FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.WATER_VAPOR_GAS, new TranslucentGasRenderHandler(ModFluids.WATER_VAPOR_GAS)); + FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.WATER_VAPOR_GAS, new TranslucentGasRenderer(ModFluids.WATER_VAPOR_GAS)); FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.HOT_STEAM_GAS, new TransparentGasRenderHandler()); - FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.SULFURIC_GAS, new TranslucentGasRenderHandler(ModFluids.SULFURIC_GAS)); - FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.CHLORIC_GAS, new TranslucentGasRenderHandler(ModFluids.CHLORIC_GAS)); - FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.STRONGLY_REDUCING_GAS, new TranslucentGasRenderHandler(ModFluids.STRONGLY_REDUCING_GAS)); - FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.STRONGLY_OXIDIZING_GAS, new TranslucentGasRenderHandler(ModFluids.STRONGLY_OXIDIZING_GAS)); + FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.SULFURIC_GAS, new DebugGasRenderHandler(ModFluids.SULFURIC_GAS)); + FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.CHLORIC_GAS, new TranslucentGasRenderer(ModFluids.CHLORIC_GAS)); + FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.STRONGLY_REDUCING_GAS, new TranslucentGasRenderer(ModFluids.STRONGLY_REDUCING_GAS)); + FluidRenderHandlerRegistry.INSTANCE.register(ModFluids.STRONGLY_OXIDIZING_GAS, new TranslucentGasRenderer(ModFluids.STRONGLY_OXIDIZING_GAS)); Synchro.LOGGER.debug("Registered mod fluid renderers for " + Synchro.MOD_ID); } } diff --git a/src/main/resources/assets/minecraft/textures/block/pink_stained_glass.png b/src/main/resources/assets/minecraft/textures/block/pink_stained_glass.png new file mode 100644 index 0000000..0831ab6 Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/block/pink_stained_glass.png differ diff --git a/src/main/resources/assets/synchro/textures/block/gas.png b/src/main/resources/assets/synchro/textures/block/gas.png new file mode 100644 index 0000000..e425ad5 Binary files /dev/null and b/src/main/resources/assets/synchro/textures/block/gas.png differ