From 00e3286ad9ed827cb017793fa1d58cf01194c396 Mon Sep 17 00:00:00 2001 From: grimmauld Date: Sun, 18 Apr 2021 17:30:29 +0200 Subject: [PATCH] Finally, properly angled beams --- .../create/content/optics/BeamSegment.java | 41 ++++++++- .../create/content/optics/ILightHandler.java | 25 +++--- .../content/optics/mirror/MirrorRenderer.java | 83 ++++++++++--------- .../optics/mirror/MirrorTileEntity.java | 54 +++++++----- .../create/foundation/collision/Matrix3d.java | 11 +++ 5 files changed, 132 insertions(+), 82 deletions(-) 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 ac1434292..8e3d8efbf 100644 --- a/src/main/java/com/simibubi/create/content/optics/BeamSegment.java +++ b/src/main/java/com/simibubi/create/content/optics/BeamSegment.java @@ -1,23 +1,35 @@ package com.simibubi.create.content.optics; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; +import net.minecraft.util.LazyValue; +import net.minecraft.util.math.vector.Quaternion; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.math.vector.Vector3f; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + import javax.annotation.Nonnull; -import net.minecraft.util.LazyValue; -import net.minecraft.util.math.vector.Vector3d; +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 int length; private final LazyValue normalized; + private final LazyValue beaconBeamModifier; + private final ILightHandler handler; + private int length; - public BeamSegment(@Nonnull float[] color, Vector3d start, Vector3d direction) { + public BeamSegment(ILightHandler handler, @Nonnull float[] color, Vector3d start, Vector3d direction) { + this.handler = handler; this.colors = color; this.direction = direction; this.start = start; this.length = 1; this.normalized = new LazyValue<>(direction::normalize); + beaconBeamModifier = new LazyValue<>(this::constructBeaconModifierQuat); } public void incrementLength() { @@ -43,4 +55,25 @@ public class BeamSegment { public Vector3d getNormalized() { return normalized.getValue(); } + + public ILightHandler getHandler() { + return handler; + } + + @OnlyIn(Dist.CLIENT) + private Quaternion constructBeaconModifierQuat() { + 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))))); + } + + @OnlyIn(Dist.CLIENT) + public Quaternion getBeaconBeamModifier() { + return beaconBeamModifier.getValue(); + } } 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 2cd8afaee..6c2978207 100644 --- a/src/main/java/com/simibubi/create/content/optics/ILightHandler.java +++ b/src/main/java/com/simibubi/create/content/optics/ILightHandler.java @@ -1,11 +1,5 @@ package com.simibubi.create.content.optics; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; - -import javax.annotation.Nullable; - import com.simibubi.create.foundation.utility.BeaconHelper; import com.simibubi.create.foundation.utility.VecHelper; @@ -13,16 +7,18 @@ import net.minecraft.block.BlockState; import net.minecraft.block.Blocks; import net.minecraft.item.DyeColor; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; 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.Nullable; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; public interface ILightHandler> { - Vector3d getBeamDirection(); - default Collection constructOutBeam(Vector3d beamDirection) { ArrayList beam = new ArrayList<>(); float[] segmentColor = getSegmentStartColor(); @@ -32,7 +28,7 @@ public interface ILightHandler> { Vector3d direction = VecHelper.step(beamDirection); Vector3d testPos = VecHelper.getCenterOf(getTile().getPos()); - BeamSegment segment = new BeamSegment(segmentColor, testPos, direction); + BeamSegment segment = new BeamSegment(this, segmentColor, testPos, direction); beam.add(segment); for (int i = 0; i < 128; i++) { @@ -50,7 +46,7 @@ public interface ILightHandler> { } } else if (!Arrays.equals(segmentColor, newColor)) { segmentColor = new float[]{(segment.colors[0] + newColor[0]) / 2.0F, (segment.colors[1] + newColor[1]) / 2.0F, (segment.colors[2] + newColor[2]) / 2.0F}; - segment = new BeamSegment(newColor, testPos, direction); + segment = new BeamSegment(this, newColor, testPos, direction); beam.add(segment); continue; } @@ -69,8 +65,7 @@ public interface ILightHandler> { } @Nullable - @OnlyIn(Dist.CLIENT) - default Vector3f getBeamRotationAround() { + default Direction getBeamRotationAround() { return null; } 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 6ea9cbe71..3b376464f 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,10 +1,5 @@ package com.simibubi.create.content.optics.mirror; -import static com.simibubi.create.foundation.utility.VecHelper.UP; -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; @@ -25,36 +20,40 @@ import net.minecraft.util.math.vector.Matrix3f; import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Vector3f; +import javax.annotation.ParametersAreNonnullByDefault; + +import static net.minecraft.client.renderer.tileentity.BeaconTileEntityRenderer.TEXTURE_BEACON_BEAM; + @ParametersAreNonnullByDefault public class MirrorRenderer extends KineticTileEntityRenderer { public MirrorRenderer(TileEntityRendererDispatcher dispatcher) { super(dispatcher); } - private static void method_22741(MatrixStack ms, IVertexBuilder builder, float[] colors, float p_228840_5_, int p_228840_6_, int p_228840_7_, 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_) { + private static void renderBeam(MatrixStack ms, IVertexBuilder builder, float[] colors, 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 matrix4f = matrixstack$entry.getModel(); - Matrix3f matrix3f = matrixstack$entry.getNormal(); - method_22740(matrix4f, matrix3f, builder, colors[0], colors[1], colors[2], p_228840_5_, p_228840_6_, p_228840_7_, p_228840_8_, p_228840_9_, p_228840_10_, p_228840_11_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_); - method_22740(matrix4f, matrix3f, builder, colors[0], colors[1], colors[2], p_228840_5_, p_228840_6_, p_228840_7_, p_228840_14_, p_228840_15_, p_228840_12_, p_228840_13_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_); - method_22740(matrix4f, matrix3f, builder, colors[0], colors[1], colors[2], p_228840_5_, p_228840_6_, p_228840_7_, p_228840_10_, p_228840_11_, p_228840_14_, p_228840_15_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_); - method_22740(matrix4f, matrix3f, builder, colors[0], colors[1], colors[2], p_228840_5_, p_228840_6_, p_228840_7_, p_228840_12_, p_228840_13_, p_228840_8_, p_228840_9_, p_228840_16_, p_228840_17_, p_228840_18_, p_228840_19_); + Matrix4f model = matrixstack$entry.getModel(); + Matrix3f normal = matrixstack$entry.getNormal(); + putVertices(model, normal, builder, colors, 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, 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, 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, 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 method_22740(Matrix4f matrix, Matrix3f p_228839_1_, IVertexBuilder builder, float p_228839_3_, float p_228839_4_, float p_228839_5_, float p_228839_6_, int p_228839_7_, int p_228839_8_, 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_) { - method_23076(matrix, p_228839_1_, builder, p_228839_3_, p_228839_4_, p_228839_5_, p_228839_6_, p_228839_8_, p_228839_9_, p_228839_10_, p_228839_14_, p_228839_15_); - method_23076(matrix, p_228839_1_, builder, p_228839_3_, p_228839_4_, p_228839_5_, p_228839_6_, p_228839_7_, p_228839_9_, p_228839_10_, p_228839_14_, p_228839_16_); - method_23076(matrix, p_228839_1_, builder, p_228839_3_, p_228839_4_, p_228839_5_, p_228839_6_, p_228839_7_, p_228839_11_, p_228839_12_, p_228839_13_, p_228839_16_); - method_23076(matrix, p_228839_1_, builder, p_228839_3_, p_228839_4_, p_228839_5_, p_228839_6_, p_228839_8_, p_228839_11_, p_228839_12_, p_228839_13_, p_228839_15_); + private static void putVertices(Matrix4f model, Matrix3f normal, IVertexBuilder builder, float[] colors, 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, (float) length, p_228839_9_, p_228839_10_, p_228839_14_, p_228839_15_); + putVertex(model, normal, builder, colors, (float) segemntLength, p_228839_9_, p_228839_10_, p_228839_14_, p_228839_16_); + putVertex(model, normal, builder, colors, (float) segemntLength, p_228839_11_, p_228839_12_, p_228839_13_, p_228839_16_); + putVertex(model, normal, builder, colors, (float) length, p_228839_11_, p_228839_12_, p_228839_13_, p_228839_15_); } - private static void method_23076(Matrix4f p_228838_0_, Matrix3f p_228838_1_, IVertexBuilder builder, float p_228838_3_, float p_228838_4_, float p_228838_5_, float p_228838_6_, int p_228838_7_, float p_228838_8_, float p_228838_9_, float p_228838_10_, float p_228838_11_) { - builder.vertex(p_228838_0_, p_228838_8_, (float) p_228838_7_, p_228838_9_) - .color(p_228838_3_, p_228838_4_, p_228838_5_, p_228838_6_) - .texture(p_228838_10_, p_228838_11_) + private static void putVertex(Matrix4f model, Matrix3f normal, IVertexBuilder builder, float[] colors, float vertexY, float vertexX, float vertexZ, float textureX, float textureY) { + builder.vertex(model, vertexX, vertexY, vertexZ) + .color(colors[0], colors[1], colors[2], 1f) + .texture(textureX, textureY) .overlay(OverlayTexture.DEFAULT_UV) .light(15728880) - .normal(p_228838_1_, 0.0F, 1.0F, 0.0F) + .normal(normal, 0.0F, 1.0F, 0.0F) .endVertex(); } @@ -72,36 +71,38 @@ public class MirrorRenderer extends KineticTileEntityRenderer { } private void renderOutBeam(MirrorTileEntity mirrorTe, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer) { - - int start = 0; - + double totalLength = 0; for (int k = 0; k < mirrorTe.beam.size(); k++) { BeamSegment beamSegment = mirrorTe.beam.get(k); - renderSegment(mirrorTe, beamSegment, ms, buffer, partialTicks, mirrorTe.getWorld() + double beamLength = beamSegment.getDirection() + .scale(beamSegment.getLength()) + .length(); + + renderSegment(beamSegment, ms, buffer, partialTicks, mirrorTe.getWorld() .getGameTime(), - beamSegment.getDirection() - .scale(start + beamSegment.getLength()) - .length()); - start += beamSegment.getLength(); + beamLength, + totalLength + ); + totalLength += beamLength; } } - private void renderSegment(MirrorTileEntity mirrorTe, BeamSegment beamSegment, MatrixStack ms, IRenderTypeBuffer buffer, float partialTicks, long gameTime, double length) { + 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, 0.5D, 0.5D); - ms.multiply(mirrorTe.getBeamRotationAround() - .getRadialQuaternion((float) Math.acos(beamSegment.getNormalized() - .dotProduct(UP)))); - ms.translate(0, -0.5D, -0.5D); + 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.0D, 0.5D); + ms.translate(0.5D, 0.5D, 0.5D); ms.push(); ms.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(adjustedGameTime * 2.25F - 45.0F)); - float f2 = MathHelper.fractionalPart(-adjustedGameTime * 0.2F - (float) MathHelper.floor(-adjustedGameTime * 0.1F)); - float f15 = f2 - 1; - float f16 = (float) beamSegment.getLength() * 1F * (0.5F / 0.2F) + f15; - method_22741(ms, buffer.getBuffer(RenderType.getBeaconBeam(TEXTURE_BEACON_BEAM, true)), beamSegment.colors, 1F, MathHelper.floor(length - beamSegment.getLength()), MathHelper.floor(length), 0F, 0.2F, .2F, 0F, -.2f, 0f, 0f, -.2f, 0f, 1f, f16, f15); + 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, true)), beamSegment.colors, + prevLength, totalLength, 0F, 0.2F, .2F, 0F, -.2f, + 0f, 0f, -.2f, 0f, 1f, textureOffset2, textureOffset1); ms.pop(); ms.pop(); ms.pop(); diff --git a/src/main/java/com/simibubi/create/content/optics/mirror/MirrorTileEntity.java b/src/main/java/com/simibubi/create/content/optics/mirror/MirrorTileEntity.java index a80909828..036dbc00d 100644 --- a/src/main/java/com/simibubi/create/content/optics/mirror/MirrorTileEntity.java +++ b/src/main/java/com/simibubi/create/content/optics/mirror/MirrorTileEntity.java @@ -1,14 +1,10 @@ package com.simibubi.create.content.optics.mirror; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import javax.annotation.Nonnull; - import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.optics.BeamSegment; import com.simibubi.create.content.optics.ILightHandler; +import com.simibubi.create.foundation.collision.Matrix3d; +import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.BeaconHelper; import com.simibubi.create.foundation.utility.ServerSpeedProvider; import com.simibubi.create.foundation.utility.VecHelper; @@ -22,9 +18,12 @@ import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Vector3d; -import net.minecraft.util.math.vector.Vector3f; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; + +import javax.annotation.Nonnull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; public class MirrorTileEntity extends KineticTileEntity implements ILightHandler { public final List beam; @@ -83,14 +82,29 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler float angularSpeed = getAngularSpeed(); float newAngle = angle + angularSpeed; angle = newAngle % 360; + + if (angle != prevAngle) + updateBeams(); + } + + private void updateBeams() { + beacon = BeaconHelper.getBeaconTE(pos, world); + beam.clear(); + beam.addAll(constructOutBeam(getReflectionAngle(VecHelper.UP))); + } + + private Vector3d getReflectionAngle(Vector3d inputAngle) { + inputAngle = inputAngle.normalize(); + Vector3d normal = new Matrix3d().asIdentity() + .asAxisRotation(getAxis(), AngleHelper.rad(angle)) + .transform(inputAngle); + return VecHelper.step(inputAngle.subtract(normal.scale(2 * inputAngle.dotProduct(normal)))); } @Override public void lazyTick() { super.lazyTick(); - beacon = BeaconHelper.getBeaconTE(pos, world); - beam.clear(); - beam.addAll(constructOutBeam(getBeamDirection())); + updateBeams(); } @Override @@ -98,12 +112,6 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler return true; } - @Override - public Vector3d getBeamDirection() { - // TODO: Implement properly - return VecHelper.step(Vector3d.of(Direction.SOUTH.getDirectionVec())); - } - @Override public MirrorTileEntity getTile() { return this; @@ -120,11 +128,9 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler } @Nonnull - @OnlyIn(Dist.CLIENT) @Override - public Vector3f getBeamRotationAround() { - return Direction.getFacingFromAxisDirection(getBlockState().get(BlockStateProperties.AXIS), Direction.AxisDirection.POSITIVE) - .getUnitVector(); + public Direction getBeamRotationAround() { + return Direction.getFacingFromAxisDirection(getAxis(), Direction.AxisDirection.POSITIVE); } public float getAngle() { @@ -134,4 +140,8 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler public void setAngle(float forcedAngle) { angle = forcedAngle; } + + private Direction.Axis getAxis() { + return getBlockState().get(BlockStateProperties.AXIS); + } } diff --git a/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java b/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java index 20cbef687..9e8202ffc 100644 --- a/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java +++ b/src/main/java/com/simibubi/create/foundation/collision/Matrix3d.java @@ -1,5 +1,6 @@ package com.simibubi.create.foundation.collision; +import net.minecraft.util.Direction; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Vector3d; @@ -144,4 +145,14 @@ public class Matrix3d { return new Matrix4f(conversionBuffer); } + public Matrix3d asAxisRotation(Direction.Axis axis, float rad) { + switch (axis) { + case X: + return asXRotation(rad); + case Y: + return asYRotation(rad); + default: + return asZRotation(rad); + } + } }