From a2e2e2a3130557edb8b2d828e69e978a83b72d51 Mon Sep 17 00:00:00 2001 From: grimmauld Date: Tue, 20 Apr 2021 11:43:57 +0200 Subject: [PATCH] Fix weird recursions in specific setups, Fix normal calculation being broken on mirrors placed with axis y --- .../simibubi/create/content/optics/Beam.java | 12 +++--- .../create/content/optics/BeamSegment.java | 27 +++++++------ .../optics/mirror/MirrorTileEntity.java | 40 ++++++++++++------- .../create/foundation/utility/VecHelper.java | 1 + 4 files changed, 47 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/simibubi/create/content/optics/Beam.java b/src/main/java/com/simibubi/create/content/optics/Beam.java index 3eba0e18d..11bee4a3e 100644 --- a/src/main/java/com/simibubi/create/content/optics/Beam.java +++ b/src/main/java/com/simibubi/create/content/optics/Beam.java @@ -1,11 +1,5 @@ package com.simibubi.create.content.optics; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -import javax.annotation.Nullable; - import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.foundation.utility.VecHelper; @@ -15,6 +9,12 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.vector.Vector3d; +import javax.annotation.Nullable; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + public class Beam extends ArrayList { private final Set> lightEventListeners; @Nullable 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 d74163a8a..4d64654c6 100644 --- a/src/main/java/com/simibubi/create/content/optics/BeamSegment.java +++ b/src/main/java/com/simibubi/create/content/optics/BeamSegment.java @@ -1,11 +1,5 @@ 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; @@ -18,15 +12,17 @@ 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.util.math.vector.*; import net.minecraft.world.World; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import static com.simibubi.create.foundation.utility.VecHelper.UP; +import static net.minecraft.client.renderer.tileentity.BeaconTileEntityRenderer.TEXTURE_BEACON_BEAM; + public class BeamSegment { public final float[] colors; private final Vector3d direction; @@ -120,7 +116,14 @@ public class BeamSegment { beaconBeamModifier = Quaternion.IDENTITY; } else { Vector3f unitVec = axis.getUnitVector(); - beaconBeamModifier = unitVec.getRadialQuaternion((float) Math.acos(dotProd) * (new Vector3d(unitVec).dotProduct(getNormalized().crossProduct(UP)) > 0 ? -1 : 1)); + beaconBeamModifier = unitVec.getRadialQuaternion((float) Math.acos(dotProd) * (new Vector3d(unitVec).dotProduct(getNormalized().crossProduct(UP)) > 0 + ^ axis.getAxis() + .isVertical() ? -1 : 1)); + if (axis.getAxis() + .isVertical()) { + beaconBeamModifier.multiply(unitVec.getDegreesQuaternion(-90)); + beaconBeamModifier.multiply(new Vector3f(getNormalized().crossProduct(Vector3d.of(axis.getDirectionVec()))).getDegreesQuaternion(90)); + } } } return beaconBeamModifier; 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 1353eb466..898e60ec3 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,16 +1,5 @@ package com.simibubi.create.content.optics.mirror; -import java.util.Collections; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Objects; -import java.util.function.Predicate; -import java.util.stream.Stream; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - import com.google.common.collect.Iterators; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.optics.Beam; @@ -33,6 +22,13 @@ import net.minecraft.util.math.vector.Vector3d; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import java.util.*; +import java.util.function.Predicate; +import java.util.stream.Stream; + public class MirrorTileEntity extends KineticTileEntity implements ILightHandler { protected float angle; protected float clientAngleDiff; @@ -41,6 +37,7 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler @Nullable private BeaconTileEntity beacon; private Beam beaconBeam = null; + private boolean isUpdating = false; public MirrorTileEntity(TileEntityType typeIn) { super(typeIn); @@ -122,8 +119,12 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler @Override public void updateBeams() { + if (isUpdating) + return; + isUpdating = true; + Map newBeams = new HashMap<>(); - for (Map.Entry entry : beams.entrySet()) { + for (Map.Entry entry : new HashSet<>(beams.entrySet())) { entry.getValue() .onRemoved(); if (entry.getKey() @@ -138,13 +139,22 @@ public class MirrorTileEntity extends KineticTileEntity implements ILightHandler } } beams = newBeams; + isUpdating = false; } private Vector3d getReflectionAngle(Vector3d inputAngle) { inputAngle = inputAngle.normalize(); - Vector3d normal = new Matrix3d().asIdentity() - .asAxisRotation(getBlockState().get(BlockStateProperties.AXIS), AngleHelper.rad(angle)) - .transform(VecHelper.UP); + Direction.Axis axis = getBlockState().get(BlockStateProperties.AXIS); + Vector3d normal; + if (axis.isHorizontal()) + normal = new Matrix3d().asIdentity() + .asAxisRotation(axis, AngleHelper.rad(angle)) + .transform(VecHelper.UP); + else + normal = new Matrix3d().asIdentity() + .asAxisRotation(axis, AngleHelper.rad(-angle)) + .transform(VecHelper.SOUTH); + return inputAngle.subtract(normal.scale(2 * inputAngle.dotProduct(normal))); } diff --git a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java index bc2f288e3..25872c26f 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -23,6 +23,7 @@ public class VecHelper { public static final Vector3d CENTER_OF_ORIGIN = new Vector3d(.5, .5, .5); public static final Vector3d UP = new Vector3d(0, 1, 0); + public static final Vector3d SOUTH = new Vector3d(1, 0, 0); public static Vector3d rotate(Vector3d vec, Vector3d rotationVec) { return rotate(vec, rotationVec.x, rotationVec.y, rotationVec.z);