diff --git a/src/main/java/com/simibubi/create/foundation/mixin/FixInverseCbrtMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/FixInverseCbrtMixin.java deleted file mode 100644 index f4b7b1f87..000000000 --- a/src/main/java/com/simibubi/create/foundation/mixin/FixInverseCbrtMixin.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.simibubi.create.foundation.mixin; - -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.ModifyVariable; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import net.minecraft.util.math.MathHelper; - -/** - * Vanilla's fast inverse cube root function returns nonsensical results for negative - * numbers, which results in incorrect vertex normal scaling. By negating the input - * and output accordingly, this issue can be prevented. - */ -@Mixin(MathHelper.class) -public class FixInverseCbrtMixin { - @ModifyVariable(at = @At("HEAD"), method = "fastInverseCbrt(F)F") - private static float negateAtHead(float input) { - if (input < 0) { - input *= -1; - } - return input; - } - - @Inject(at = @At("TAIL"), method = "fastInverseCbrt(F)F", cancellable = true) - private static void negateAtTail(float input, CallbackInfoReturnable cir) { - if (input < 0) { - cir.setReturnValue(cir.getReturnValueF() * -1); - } - } -} diff --git a/src/main/java/com/simibubi/create/foundation/mixin/FixNormalScalingMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/FixNormalScalingMixin.java new file mode 100644 index 000000000..46b35d6e3 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/mixin/FixNormalScalingMixin.java @@ -0,0 +1,36 @@ +package com.simibubi.create.foundation.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.At.Shift; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.mojang.blaze3d.matrix.MatrixStack; + +@Mixin(MatrixStack.class) +public class FixNormalScalingMixin { + /** + * Minecraft negates the normal matrix if all scales are equal and negative, but + * does not return afterward. This allows the rest of the method's logic to be + * applied, which negates the matrix again, resulting in the matrix being the + * same as in the beginning. + */ + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/vector/Matrix3f;multiply(F)V", shift = Shift.AFTER), method = "scale(FFF)V", cancellable = true) + private void returnAfterNegate(float x, float y, float z, CallbackInfo ci) { + ci.cancel(); + } + + /** + * Minecraft takes the inverse cube root of the product of all scales to provide a + * rough estimate for normalization so that it does not need to be done later. It + * does not make sense for this "normalization factor" to be negative though, as + * that would invert all normals. Additionally, Minecraft's fastInverseCbrt method + * does not work for negative numbers. + */ + @ModifyArg(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/MathHelper;fastInverseCbrt(F)F"), method = "scale(FFF)V") + private float absInvCbrtInput(float input) { + return Math.abs(input); + } +} diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index 49a8c2376..3bc4de366 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -9,7 +9,7 @@ "client": [ "CancelTileEntityRenderMixin", "EntityContraptionInteractionMixin", - "FixInverseCbrtMixin", + "FixNormalScalingMixin", "FogColorTrackerMixin", "HeavyBootsOnPlayerMixin", "LightUpdateMixin",