diff --git a/src/main/java/com/simibubi/create/content/optics/BeamSegment.java b/src/main/java/com/simibubi/create/content/optics/BeamSegment.java index 8e3d8efbf..2c95bf5c5 100644 --- a/src/main/java/com/simibubi/create/content/optics/BeamSegment.java +++ b/src/main/java/com/simibubi/create/content/optics/BeamSegment.java @@ -1,25 +1,41 @@ package com.simibubi.create.content.optics; +import static com.simibubi.create.foundation.utility.VecHelper.UP; +import static net.minecraft.client.renderer.tileentity.BeaconTileEntityRenderer.TEXTURE_BEACON_BEAM; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import com.simibubi.create.foundation.utility.MatrixStacker; +import com.simibubi.create.foundation.utility.VecHelper; + +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.Direction; import net.minecraft.util.LazyValue; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.vector.Matrix3f; +import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Quaternion; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3f; +import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; -import javax.annotation.Nonnull; - -import static com.simibubi.create.foundation.utility.VecHelper.UP; - public class BeamSegment { public final float[] colors; private final Vector3d direction; private final Vector3d start; private final LazyValue normalized; - private final LazyValue beaconBeamModifier; + private final LazyValue totalSectionLength; private final ILightHandler handler; + @Nullable + private Quaternion beaconBeamModifier; private int length; public BeamSegment(ILightHandler handler, @Nonnull float[] color, Vector3d start, Vector3d direction) { @@ -29,7 +45,39 @@ public class BeamSegment { this.start = start; this.length = 1; this.normalized = new LazyValue<>(direction::normalize); - beaconBeamModifier = new LazyValue<>(this::constructBeaconModifierQuat); + beaconBeamModifier = null; + totalSectionLength = new LazyValue<>(() -> getDirection().scale(getLength()) + .length()); + } + + @OnlyIn(Dist.CLIENT) + private static void renderBeam(MatrixStack ms, IVertexBuilder builder, float[] colors, float alpha, double segemntLength, double length, float p_228840_9_, float p_228840_10_, float p_228840_11_, float p_228840_12_, float p_228840_13_, float p_228840_14_, float p_228840_15_, float p_228840_18_, float p_228840_19_) { + MatrixStack.Entry matrixstack$entry = ms.peek(); + Matrix4f model = matrixstack$entry.getModel(); + Matrix3f normal = matrixstack$entry.getNormal(); + putVertices(model, normal, builder, colors, alpha, segemntLength, length, (float) 0.0, p_228840_9_, p_228840_10_, p_228840_11_, p_228840_18_, p_228840_19_); + putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_14_, p_228840_15_, p_228840_12_, p_228840_13_, p_228840_18_, p_228840_19_); + putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_10_, p_228840_11_, p_228840_14_, p_228840_15_, p_228840_18_, p_228840_19_); + putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_12_, p_228840_13_, (float) 0.0, p_228840_9_, p_228840_18_, p_228840_19_); + } + + @OnlyIn(Dist.CLIENT) + private static void putVertices(Matrix4f model, Matrix3f normal, IVertexBuilder builder, float[] colors, float alpha, double segemntLength, double length, float p_228839_9_, float p_228839_10_, float p_228839_11_, float p_228839_12_, float p_228839_15_, float p_228839_16_) { + putVertex(model, normal, builder, colors, alpha, (float) length, p_228839_9_, p_228839_10_, (float) 1.0, p_228839_15_); + putVertex(model, normal, builder, colors, alpha, (float) segemntLength, p_228839_9_, p_228839_10_, (float) 1.0, p_228839_16_); + putVertex(model, normal, builder, colors, alpha, (float) segemntLength, p_228839_11_, p_228839_12_, (float) 0.0, p_228839_16_); + putVertex(model, normal, builder, colors, alpha, (float) length, p_228839_11_, p_228839_12_, (float) 0.0, p_228839_15_); + } + + @OnlyIn(Dist.CLIENT) + private static void putVertex(Matrix4f model, Matrix3f normal, IVertexBuilder builder, float[] colors, float alpha, float vertexY, float vertexX, float vertexZ, float textureX, float textureY) { + builder.vertex(model, vertexX, vertexY, vertexZ) + .color(colors[0], colors[1], colors[2], alpha) + .texture(textureX, textureY) + .overlay(OverlayTexture.DEFAULT_UV) + .light(15728880) + .normal(normal, 0.0F, 1.0F, 0.0F) + .endVertex(); } public void incrementLength() { @@ -61,19 +109,61 @@ public class BeamSegment { } @OnlyIn(Dist.CLIENT) - private Quaternion constructBeaconModifierQuat() { - double dotProd = getNormalized() - .dotProduct(UP); + @Nonnull + public Quaternion getBeaconBeamModifier() { + if (beaconBeamModifier == null) { + double dotProd = getNormalized() + .dotProduct(UP); - Direction axis = getHandler().getBeamRotationAround(); - if (axis == null) - return Quaternion.IDENTITY; - Vector3f unitVec = axis.getUnitVector(); - return unitVec.getRadialQuaternion((float) (-Math.acos(dotProd) * Math.signum(new Vector3d(unitVec).dotProduct(getNormalized().crossProduct(UP))))); + Direction axis = getHandler().getBeamRotationAround(); + if (axis == null) { + beaconBeamModifier = Quaternion.IDENTITY; + } else { + Vector3f unitVec = axis.getUnitVector(); + beaconBeamModifier = unitVec.getRadialQuaternion((float) (-Math.acos(dotProd) * Math.signum(new Vector3d(unitVec).dotProduct(getNormalized().crossProduct(UP))))); + } + } + return beaconBeamModifier; + } + + public double getTotalSectionLength() { + return totalSectionLength.getValue(); + } + + public long getWorldTick() { + World world = getHandler() + .getTile() + .getWorld(); + if (world == null) + return 0; + return world.getGameTime(); } @OnlyIn(Dist.CLIENT) - public Quaternion getBeaconBeamModifier() { - return beaconBeamModifier.getValue(); + public void renderSegment(MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks, double segmentOffset) { + float adjustedGameTime = (float) Math.floorMod(getWorldTick(), 40L) + partialTicks; + double totalLength = totalSectionLength.getValue() + segmentOffset; + float textureOffset1 = MathHelper.fractionalPart(-adjustedGameTime * 0.2F - (float) MathHelper.floor(-adjustedGameTime * 0.1F)) - 1; + float textureOffset2 = (float) this.getLength() * 2.5f + textureOffset1; + + MatrixStacker stacker = MatrixStacker.of(ms) + .push() + .translate(getStart().subtract(VecHelper.getCenterOf(getHandler().getTile() + .getPos()))) + .push() + .translate(VecHelper.CENTER_OF_ORIGIN) + .multiply(getBeaconBeamModifier()) + .push() + .multiply(Vector3f.POSITIVE_Y, adjustedGameTime * 2.25F - 45.0F); + + renderBeam(stacker.unwrap(), buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, false)), this.colors, 1F, + segmentOffset, totalLength, 0.2F, .2F, 0F, -.2f, + 0f, 0f, -.2f, textureOffset2, textureOffset1); + stacker.pop(); + renderBeam(stacker.unwrap(), buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, true)), this.colors, 0.125F, + segmentOffset, totalLength, -.25f, .25f, -.25f, -.25f, + .25f, .25f, .25f, textureOffset2, textureOffset1); + stacker.pop() + .pop(); } } diff --git a/src/main/java/com/simibubi/create/content/optics/ILightHandler.java b/src/main/java/com/simibubi/create/content/optics/ILightHandler.java index 6c2978207..60926dbca 100644 --- a/src/main/java/com/simibubi/create/content/optics/ILightHandler.java +++ b/src/main/java/com/simibubi/create/content/optics/ILightHandler.java @@ -1,5 +1,11 @@ package com.simibubi.create.content.optics; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import javax.annotation.Nullable; + import com.simibubi.create.foundation.utility.BeaconHelper; import com.simibubi.create.foundation.utility.VecHelper; @@ -12,14 +18,8 @@ import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.World; -import javax.annotation.Nullable; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; - public interface ILightHandler> { - default Collection constructOutBeam(Vector3d beamDirection) { + default List constructOutBeam(Vector3d beamDirection) { ArrayList beam = new ArrayList<>(); float[] segmentColor = getSegmentStartColor(); World world = getTile().getWorld(); diff --git a/src/main/java/com/simibubi/create/content/optics/mirror/MirrorRenderer.java b/src/main/java/com/simibubi/create/content/optics/mirror/MirrorRenderer.java index 1fe5f710b..37793d8d2 100644 --- a/src/main/java/com/simibubi/create/content/optics/mirror/MirrorRenderer.java +++ b/src/main/java/com/simibubi/create/content/optics/mirror/MirrorRenderer.java @@ -1,11 +1,8 @@ package com.simibubi.create.content.optics.mirror; -import static net.minecraft.client.renderer.tileentity.BeaconTileEntityRenderer.TEXTURE_BEACON_BEAM; - import javax.annotation.ParametersAreNonnullByDefault; import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; @@ -15,14 +12,9 @@ import com.simibubi.create.foundation.utility.AngleHelper; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.Direction; -import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.vector.Matrix3f; -import net.minecraft.util.math.vector.Matrix4f; -import net.minecraft.util.math.vector.Vector3f; @ParametersAreNonnullByDefault public class MirrorRenderer extends KineticTileEntityRenderer { @@ -30,33 +22,6 @@ public class MirrorRenderer extends KineticTileEntityRenderer { super(dispatcher); } - private static void renderBeam(MatrixStack ms, IVertexBuilder builder, float[] colors, float alpha, double segemntLength, double length, float p_228840_8_, float p_228840_9_, float p_228840_10_, float p_228840_11_, float p_228840_12_, float p_228840_13_, float p_228840_14_, float p_228840_15_, float p_228840_16_, float p_228840_17_, float p_228840_18_, float p_228840_19_) { - MatrixStack.Entry matrixstack$entry = ms.peek(); - Matrix4f model = matrixstack$entry.getModel(); - Matrix3f normal = matrixstack$entry.getNormal(); - putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_8_, p_228840_9_, p_228840_10_, p_228840_11_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_); - putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_14_, p_228840_15_, p_228840_12_, p_228840_13_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_); - putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_10_, p_228840_11_, p_228840_14_, p_228840_15_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_); - putVertices(model, normal, builder, colors, alpha, segemntLength, length, p_228840_12_, p_228840_13_, p_228840_8_, p_228840_9_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_); - } - - private static void putVertices(Matrix4f model, Matrix3f normal, IVertexBuilder builder, float[] colors, float alpha, double segemntLength, double length, float p_228839_9_, float p_228839_10_, float p_228839_11_, float p_228839_12_, float p_228839_13_, float p_228839_14_, float p_228839_15_, float p_228839_16_) { - putVertex(model, normal, builder, colors, alpha, (float) length, p_228839_9_, p_228839_10_, p_228839_14_, p_228839_15_); - putVertex(model, normal, builder, colors, alpha, (float) segemntLength, p_228839_9_, p_228839_10_, p_228839_14_, p_228839_16_); - putVertex(model, normal, builder, colors, alpha, (float) segemntLength, p_228839_11_, p_228839_12_, p_228839_13_, p_228839_16_); - putVertex(model, normal, builder, colors, alpha, (float) length, p_228839_11_, p_228839_12_, p_228839_13_, p_228839_15_); - } - - private static void putVertex(Matrix4f model, Matrix3f normal, IVertexBuilder builder, float[] colors, float alpha, float vertexY, float vertexX, float vertexZ, float textureX, float textureY) { - builder.vertex(model, vertexX, vertexY, vertexZ) - .color(colors[0], colors[1], colors[2], alpha) - .texture(textureX, textureY) - .overlay(OverlayTexture.DEFAULT_UV) - .light(15728880) - .normal(normal, 0.0F, 1.0F, 0.0F) - .endVertex(); - } - @Override protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { @@ -65,50 +30,17 @@ public class MirrorRenderer extends KineticTileEntityRenderer { MirrorTileEntity mirrorTe = (MirrorTileEntity) te; renderMirror(mirrorTe, partialTicks, ms, buffer, light); - renderOutBeam(mirrorTe, partialTicks, ms, buffer); + renderOutBeam(mirrorTe.beam, partialTicks, ms, buffer); } - private void renderOutBeam(MirrorTileEntity mirrorTe, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer) { + private void renderOutBeam(Iterable beam, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer) { double totalLength = 0; - for (int k = 0; k < mirrorTe.beam.size(); k++) { - BeamSegment beamSegment = mirrorTe.beam.get(k); - double beamLength = beamSegment.getDirection() - .scale(beamSegment.getLength()) - .length(); - - renderSegment(beamSegment, ms, buffer, partialTicks, mirrorTe.getWorld() - .getGameTime(), - beamLength, - totalLength - ); - totalLength += beamLength; + for (BeamSegment beamSegment : beam) { + beamSegment.renderSegment(ms, buffer, partialTicks, totalLength); + totalLength += beamSegment.getTotalSectionLength(); } } - private void renderSegment(BeamSegment beamSegment, MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks, long gameTime, double beamLength, double prevLength) { - float adjustedGameTime = (float) Math.floorMod(gameTime, 40L) + partialTicks; - double totalLength = beamLength + prevLength; - ms.push(); - ms.translate(0.5, 0.5D, 0.5D); - ms.multiply(beamSegment.getBeaconBeamModifier()); - ms.translate(-0.5D, -0.5D, -0.5D); - ms.push(); - ms.translate(0.5D, 0.5D, 0.5D); - ms.push(); - ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(adjustedGameTime * 2.25F - 45.0F)); - float textureOffset1 = MathHelper.fractionalPart(-adjustedGameTime * 0.2F - (float) MathHelper.floor(-adjustedGameTime * 0.1F)) - 1; - float textureOffset2 = (float) beamSegment.getLength() * 2.5f + textureOffset1; - renderBeam(ms, buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, false)), beamSegment.colors, 1F, - prevLength, totalLength, 0F, 0.2F, .2F, 0F, -.2f, - 0f, 0f, -.2f, 0f, 1f, textureOffset2, textureOffset1); - ms.pop(); - renderBeam(ms, buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, true)), beamSegment.colors, 0.125F, - prevLength, totalLength, 0F, -.25f, .25f, -.25f, -.25f, - .25f, .25f, .25f, 0.0F, 1.0F, textureOffset2, textureOffset1); - ms.pop(); - ms.pop(); - } - private void renderMirror(MirrorTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) { final Direction.Axis facing = te.getBlockState()