diff --git a/src/main/java/com/simibubi/create/AllTags.java b/src/main/java/com/simibubi/create/AllTags.java index b42cdf120..231973559 100644 --- a/src/main/java/com/simibubi/create/AllTags.java +++ b/src/main/java/com/simibubi/create/AllTags.java @@ -209,6 +209,7 @@ public class AllTags { AllBlockTags.WINDMILL_SAILS.includeAll(BlockTags.WOOL); AllBlockTags.BRITTLE.includeAll(BlockTags.DOORS); + AllBlockTags.BRITTLE.includeAll(BlockTags.BEDS); AllBlockTags.BRITTLE.add(Blocks.FLOWER_POT, Blocks.BELL, Blocks.COCOA); AllBlockTags.FAN_TRANSPARENT.includeAll(BlockTags.FENCES); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java b/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java index 9bc30ce82..0c965b5c6 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/SpoutCategory.java @@ -12,6 +12,7 @@ import com.simibubi.create.AllBlocks; import com.simibubi.create.Create; import com.simibubi.create.compat.jei.category.animations.AnimatedSpout; import com.simibubi.create.content.contraptions.fluids.actors.FillingRecipe; +import com.simibubi.create.content.contraptions.fluids.actors.GenericItemFilling; import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler; import com.simibubi.create.content.contraptions.processing.ProcessingRecipeBuilder; import com.simibubi.create.foundation.fluid.FluidIngredient; @@ -71,6 +72,8 @@ public class SpoutCategory extends CreateRecipeCategory { ItemStack copy = stack.copy(); copy.getCapability(CapabilityFluidHandler.FLUID_HANDLER_ITEM_CAPABILITY) .ifPresent(fhi -> { + if (!GenericItemFilling.isFluidHandlerValid(copy, fhi)) + return; FluidStack fluidCopy = fluidStack.copy(); fluidCopy.setAmount(1000); fhi.fill(fluidCopy, FluidAction.EXECUTE); diff --git a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedCrushingWheels.java b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedCrushingWheels.java index 0459efd33..263add564 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedCrushingWheels.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedCrushingWheels.java @@ -1,7 +1,6 @@ package com.simibubi.create.compat.jei.category.animations; import com.mojang.blaze3d.matrix.MatrixStack; -import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.AllBlocks; import com.simibubi.create.foundation.gui.GuiGameElement; @@ -14,11 +13,11 @@ public class AnimatedCrushingWheels extends AnimatedKinetics { @Override public void draw(MatrixStack matrixStack, int xOffset, int yOffset) { - RenderSystem.enableDepthTest(); + matrixStack.push(); matrixStack.translate(xOffset, yOffset, 100); matrixStack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(-22.5f)); int scale = 22; - + BlockState wheel = AllBlocks.CRUSHING_WHEEL.get() .getDefaultState() .with(BlockStateProperties.AXIS, Axis.X); @@ -33,6 +32,8 @@ public class AnimatedCrushingWheels extends AnimatedKinetics { .atLocal(2, 0, 0) .scale(scale) .render(matrixStack); + + matrixStack.pop(); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java index 5a47573fe..a7bfd1806 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/BlockMovementTraits.java @@ -29,6 +29,7 @@ import com.simibubi.create.content.logistics.block.redstone.RedstoneLinkBlock; import net.minecraft.block.AbstractPressurePlateBlock; import net.minecraft.block.AbstractRailBlock; import net.minecraft.block.AbstractSignBlock; +import net.minecraft.block.BedBlock; import net.minecraft.block.BellBlock; import net.minecraft.block.Block; import net.minecraft.block.BlockState; @@ -49,6 +50,7 @@ import net.minecraft.block.WallSignBlock; import net.minecraft.block.WallTorchBlock; import net.minecraft.block.material.PushReaction; import net.minecraft.state.properties.AttachFace; +import net.minecraft.state.properties.BedPart; import net.minecraft.state.properties.BellAttachment; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.tileentity.TileEntity; @@ -163,6 +165,13 @@ public class BlockMovementTraits { return direction == Direction.DOWN; if (block instanceof DoorBlock) return direction == Direction.DOWN; + if (block instanceof BedBlock) { + Direction facing = state.get(BedBlock.HORIZONTAL_FACING); + if (state.get(BedBlock.PART) == BedPart.HEAD) { + facing = facing.getOpposite(); + } + return direction == facing; + } if (block instanceof RedstoneLinkBlock) return direction.getOpposite() == state.get(RedstoneLinkBlock.FACING); if (block instanceof FlowerPotBlock) diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueRenderer.java index cd73d52ff..34bfa5f3b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/glue/SuperGlueRenderer.java @@ -13,6 +13,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.WorldRenderer; +import net.minecraft.client.renderer.culling.ClippingHelper; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererManager; import net.minecraft.client.renderer.texture.OverlayTexture; @@ -31,10 +32,8 @@ public class SuperGlueRenderer extends EntityRenderer { private ResourceLocation regular = new ResourceLocation(Create.ID, "textures/entity/super_glue/slime.png"); - private Vector3d[] quad1; - private Vector3d[] quad2; - private float[] u = { 0, 1, 1, 0 }; - private float[] v = { 0, 0, 1, 1 }; + private float[] insideQuad; + private float[] outsideQuad; public SuperGlueRenderer(EntityRendererManager renderManager) { super(renderManager); @@ -47,17 +46,23 @@ public class SuperGlueRenderer extends EntityRenderer { } @Override - public void render(SuperGlueEntity entity, float p_225623_2_, float p_225623_3_, MatrixStack ms, + public boolean shouldRender(SuperGlueEntity entity, ClippingHelper frustum, double x, double y, double z) { + if (super.shouldRender(entity, frustum, x, y, z)) { + PlayerEntity player = Minecraft.getInstance().player; + boolean visible = entity.isVisible(); + boolean holdingGlue = AllItems.SUPER_GLUE.isIn(player.getHeldItemMainhand()) + || AllItems.SUPER_GLUE.isIn(player.getHeldItemOffhand()); + + if (visible || holdingGlue) + return true; + } + return false; + } + + @Override + public void render(SuperGlueEntity entity, float yaw, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light) { - super.render(entity, p_225623_2_, p_225623_3_, ms, buffer, light); - - PlayerEntity player = Minecraft.getInstance().player; - boolean visible = entity.isVisible(); - boolean holdingGlue = AllItems.SUPER_GLUE.isIn(player.getHeldItemMainhand()) - || AllItems.SUPER_GLUE.isIn(player.getHeldItemOffhand()); - - if (!visible && !holdingGlue) - return; + super.render(entity, yaw, partialTicks, ms, buffer, light); IVertexBuilder builder = buffer.getBuffer(RenderType.getEntityCutout(getEntityTexture(entity))); light = getBrightnessForRender(entity); @@ -65,24 +70,13 @@ public class SuperGlueRenderer extends EntityRenderer { ms.push(); MatrixStacker.of(ms) - .rotateY(AngleHelper.horizontalAngle(face)) + .rotateY(AngleHelper.horizontalAngleNew(face)) .rotateX(AngleHelper.verticalAngle(face)); Entry peek = ms.peek(); - Vector3d[][] quads = { quad1, quad2 }; - for (Vector3d[] quad : quads) { - for (int i = 0; i < 4; i++) { - Vector3d vertex = quad[i]; - builder.vertex(peek.getModel(), (float) vertex.x, (float) vertex.y, (float) vertex.z) - .color(255, 255, 255, 255) - .texture(u[i], v[i]) - .overlay(OverlayTexture.DEFAULT_UV) - .light(light) - .normal(peek.getNormal(), face.getXOffset(), face.getYOffset(), face.getZOffset()) - .endVertex(); - } - face = face.getOpposite(); - } + renderQuad(builder, peek, insideQuad, light, -1); + renderQuad(builder, peek, outsideQuad, light, 1); + ms.pop(); } @@ -111,8 +105,18 @@ public class SuperGlueRenderer extends EntityRenderer { Vector3d a4 = plane.add(start); Vector3d b4 = plane.add(end); - quad1 = new Vector3d[] { a2, a3, a4, a1 }; - quad2 = new Vector3d[] { b3, b2, b1, b4 }; + insideQuad = new float[] { + (float) a1.x, (float) a1.y, (float) a1.z, 1, 0, + (float) a2.x, (float) a2.y, (float) a2.z, 1, 1, + (float) a3.x, (float) a3.y, (float) a3.z, 0, 1, + (float) a4.x, (float) a4.y, (float) a4.z, 0, 0, + }; + outsideQuad = new float[] { + (float) b4.x, (float) b4.y, (float) b4.z, 0, 0, + (float) b3.x, (float) b3.y, (float) b3.z, 0, 1, + (float) b2.x, (float) b2.y, (float) b2.z, 1, 1, + (float) b1.x, (float) b1.y, (float) b1.z, 1, 0, + }; } private int getBrightnessForRender(SuperGlueEntity entity) { @@ -126,4 +130,17 @@ public class SuperGlueRenderer extends EntityRenderer { return Math.max(light, light2); } + // Vertex format: pos x, pos y, pos z, u, v + private void renderQuad(IVertexBuilder builder, Entry matrix, float[] data, int light, float normalZ) { + for (int i = 0; i < 4; i++) { + builder.vertex(matrix.getModel(), data[5 * i], data[5 * i + 1], data[5 * i + 2]) + .color(255, 255, 255, 255) + .texture(data[5 * i + 3], data[5 * i + 4]) + .overlay(OverlayTexture.DEFAULT_UV) + .light(light) + .normal(matrix.getNormal(), 0.0f, 0.0f, normalZ) + .endVertex(); + } + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/GenericItemFilling.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/GenericItemFilling.java index 801f45fd1..271378b4d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/GenericItemFilling.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/actors/GenericItemFilling.java @@ -5,9 +5,11 @@ import com.simibubi.create.content.contraptions.fluids.potion.PotionFluidHandler import com.simibubi.create.foundation.fluid.FluidHelper; import net.minecraft.fluid.Fluids; +import net.minecraft.item.BucketItem; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; +import net.minecraft.item.MilkBucketItem; import net.minecraft.potion.PotionUtils; import net.minecraft.potion.Potions; import net.minecraft.world.World; @@ -20,6 +22,33 @@ import net.minecraftforge.fluids.capability.wrappers.FluidBucketWrapper; public class GenericItemFilling { + /** + * Checks if an ItemStack's IFluidHandlerItem is valid. Ideally, this check would + * not be necessary. Unfortunately, some mods that copy the functionality of the + * MilkBucketItem copy the FluidBucketWrapper capability that is patched in by + * Forge without looking into what it actually does. In all cases this is + * incorrect because having a non-bucket item turn into a bucket item does not + * make sense. + * + *

This check is only necessary for filling since a FluidBucketWrapper will be + * empty if it is initialized with a non-bucket item. + * + * @param stack The ItemStack. + * @param fluidHandler The IFluidHandlerItem instance retrieved from the ItemStack. + * @return If the IFluidHandlerItem is valid for the passed ItemStack. + */ + public static boolean isFluidHandlerValid(ItemStack stack, IFluidHandlerItem fluidHandler) { + // Not instanceof in case a correct subclass is made + if (fluidHandler.getClass() == FluidBucketWrapper.class) { + Item item = stack.getItem(); + // Forge does not patch the FluidBucketWrapper onto subclasses of BucketItem + if (item.getClass() != BucketItem.class && !(item instanceof MilkBucketItem)) { + return false; + } + } + return true; + } + public static boolean canItemBeFilled(World world, ItemStack stack) { if (stack.getItem() == Items.GLASS_BOTTLE) return true; @@ -31,6 +60,8 @@ public class GenericItemFilling { IFluidHandlerItem tank = capability.orElse(null); if (tank == null) return false; + if (!isFluidHandlerValid(stack, tank)) + return false; for (int i = 0; i < tank.getTanks(); i++) { if (tank.getFluidInTank(i) .getAmount() < tank.getTankCapacity(i)) diff --git a/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java b/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java index 2fd69e79f..5a110f8b7 100644 --- a/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java +++ b/src/main/java/com/simibubi/create/foundation/data/BuilderTransformers.java @@ -212,7 +212,7 @@ public class BuilderTransformers { }); }) .item() - .properties(p -> type.equals("creative") ? p : p.rarity(Rarity.EPIC)) + .properties(p -> type.equals("creative") ? p.rarity(Rarity.EPIC) : p) .transform(ModelGen.customItemModel("crate", type, "single")); } diff --git a/src/main/java/com/simibubi/create/foundation/gui/GuiGameElement.java b/src/main/java/com/simibubi/create/foundation/gui/GuiGameElement.java index 79405d4c4..b39dc489c 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/GuiGameElement.java +++ b/src/main/java/com/simibubi/create/foundation/gui/GuiGameElement.java @@ -35,12 +35,15 @@ import net.minecraft.inventory.container.PlayerContainer; import net.minecraft.item.ItemStack; import net.minecraft.util.IItemProvider; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.vector.Vector2f; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3f; import net.minecraftforge.fluids.FluidStack; public class GuiGameElement { + public static Vector2f defaultBlockLighting = new Vector2f(30.0f, 7.5f); + public static GuiRenderBuilder of(ItemStack stack) { return new GuiItemRenderBuilder(stack); } @@ -64,11 +67,13 @@ public class GuiGameElement { } public static abstract class GuiRenderBuilder extends RenderElement { - double xLocal, yLocal, zLocal; - double xRot, yRot, zRot; - double scale = 1; - int color = 0xFFFFFF; - Vector3d rotationOffset = Vector3d.ZERO; + protected double xLocal, yLocal, zLocal; + protected double xRot, yRot, zRot; + protected double scale = 1; + protected int color = 0xFFFFFF; + protected Vector3d rotationOffset = Vector3d.ZERO; + protected boolean hasCustomLighting = false; + protected float lightingXRot, lightingYRot; public GuiRenderBuilder atLocal(double x, double y, double z) { this.xLocal = x; @@ -104,33 +109,25 @@ public class GuiGameElement { return this; } - public abstract void render(MatrixStack matrixStack); + public GuiRenderBuilder lighting(float xRot, float yRot) { + hasCustomLighting = true; + lightingXRot = xRot; + lightingYRot = yRot; + return this; + } - @Deprecated - protected void prepare() {} + public abstract void render(MatrixStack matrixStack); protected void prepareMatrix(MatrixStack matrixStack) { matrixStack.push(); - RenderSystem.enableBlend(); - RenderSystem.enableRescaleNormal(); - RenderSystem.enableAlphaTest(); - RenderHelper.enableGuiDepthLighting(); - RenderSystem.alphaFunc(516, 0.1F); - RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); - } - - @Deprecated - protected void transform() { - RenderSystem.translated(x, y, 0); - RenderSystem.scaled(scale, scale, scale); - RenderSystem.translated(xLocal, yLocal, zLocal); - RenderSystem.scaled(1, -1, 1); - RenderSystem.translated(rotationOffset.x, rotationOffset.y, rotationOffset.z); - RenderSystem.rotatef((float) zRot, 0, 0, 1); - RenderSystem.rotatef((float) xRot, 1, 0, 0); - RenderSystem.rotatef((float) yRot, 0, 1, 0); - RenderSystem.translated(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z); + RenderSystem.alphaFunc(516, 0.1F); + RenderSystem.enableAlphaTest(); + RenderSystem.blendFunc(SourceFactor.SRC_ALPHA, DestFactor.ONE_MINUS_SRC_ALPHA); + RenderSystem.enableBlend(); + RenderSystem.enableDepthTest(); + RenderSystem.enableRescaleNormal(); + prepareLighting(matrixStack); } protected void transformMatrix(MatrixStack matrixStack) { @@ -145,13 +142,18 @@ public class GuiGameElement { matrixStack.translate(-rotationOffset.x, -rotationOffset.y, -rotationOffset.z); } - @Deprecated - protected void cleanUp() {} - protected void cleanUpMatrix(MatrixStack matrixStack) { matrixStack.pop(); - RenderSystem.disableAlphaTest(); RenderSystem.disableRescaleNormal(); + RenderSystem.disableAlphaTest(); + cleanUpLighting(matrixStack); + } + + protected void prepareLighting(MatrixStack matrixStack) { + RenderHelper.enableGuiDepthLighting(); + } + + protected void cleanUpLighting(MatrixStack matrixStack) { } } @@ -197,6 +199,20 @@ public class GuiGameElement { 0xF000F0, OverlayTexture.DEFAULT_UV, VirtualEmptyModelData.INSTANCE); buffer.draw(); } + + @Override + protected void prepareLighting(MatrixStack matrixStack) { + if (hasCustomLighting) { + UIRenderHelper.setupSimpleCustomLighting(lightingXRot, lightingYRot); + } else { + UIRenderHelper.setupSimpleCustomLighting(defaultBlockLighting.x, defaultBlockLighting.y); + } + } + + @Override + protected void cleanUpLighting(MatrixStack matrixStack) { + RenderHelper.enableGuiDepthLighting(); + } } public static class GuiBlockStateRenderBuilder extends GuiBlockModelRenderBuilder { @@ -214,8 +230,8 @@ public class GuiGameElement { RenderHelper.disableGuiDepthLighting(); blockRenderer.renderBlock(blockState, ms, buffer, 0xF000F0, OverlayTexture.DEFAULT_UV, VirtualEmptyModelData.INSTANCE); - RenderHelper.enable(); buffer.draw(); + RenderHelper.enableGuiDepthLighting(); return; } @@ -281,19 +297,19 @@ public class GuiGameElement { matrixStack.translate((float) 0, (float) 0, 100.0F + renderer.zLevel); matrixStack.translate(8.0F, -8.0F, 0.0F); matrixStack.scale(16.0F, 16.0F, 16.0F); - IRenderTypeBuffer.Impl irendertypebuffer$impl = Minecraft.getInstance() + IRenderTypeBuffer.Impl buffer = Minecraft.getInstance() .getBufferBuilders() .getEntityVertexConsumers(); - boolean flag = !bakedModel.isSideLit(); - if (flag) { + boolean flatLighting = !bakedModel.isSideLit(); + if (flatLighting) { RenderHelper.disableGuiDepthLighting(); } renderer.renderItem(stack, ItemCameraTransforms.TransformType.GUI, false, matrixStack, - irendertypebuffer$impl, 15728880, OverlayTexture.DEFAULT_UV, bakedModel); - irendertypebuffer$impl.draw(); + buffer, 0xF000F0, OverlayTexture.DEFAULT_UV, bakedModel); + buffer.draw(); RenderSystem.enableDepthTest(); - if (flag) { + if (flatLighting) { RenderHelper.enableGuiDepthLighting(); } diff --git a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java index be3e6b11c..fee8e48c6 100644 --- a/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java +++ b/src/main/java/com/simibubi/create/foundation/gui/UIRenderHelper.java @@ -10,6 +10,7 @@ import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.Couple; +import com.simibubi.create.foundation.utility.VecHelper; import net.minecraft.client.MainWindow; import net.minecraft.client.Minecraft; @@ -257,4 +258,14 @@ public class UIRenderHelper { RenderSystem.enableAlphaTest(); WorldVertexBufferUploader.draw(bufferbuilder); } + + public static void setupSimpleCustomLighting(float xRot, float yRot) { + Matrix4f lightingMatrix = new Matrix4f(); + lightingMatrix.loadIdentity(); + lightingMatrix.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(yRot)); + lightingMatrix.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(xRot)); + lightingMatrix.multiply(Matrix4f.translate(0, 0, 1)); + RenderSystem.setupLevelDiffuseLighting(VecHelper.ZERO_3F, VecHelper.ZERO_3F, lightingMatrix); + } + } 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/java/com/simibubi/create/foundation/utility/AngleHelper.java b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java index 9884e71c4..3f8723672 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AngleHelper.java @@ -5,6 +5,9 @@ import net.minecraft.util.Direction.Axis; public class AngleHelper { + /** + * Legacy method. See {@link #horizontalAngleNew(Direction)} for new method. + */ public static float horizontalAngle(Direction facing) { float angle = facing.getHorizontalAngle(); if (facing.getAxis() == Axis.X) @@ -12,6 +15,19 @@ public class AngleHelper { return angle; } + /** + * Same as {@link #horizontalAngle(Direction)}, but returns 0 instead of -90 for vertical directions. + */ + public static float horizontalAngleNew(Direction facing) { + if (facing.getAxis().isVertical()) { + return 0; + } + float angle = facing.getHorizontalAngle(); + if (facing.getAxis() == Axis.X) + angle = -angle; + return angle; + } + public static float verticalAngle(Direction facing) { return facing == Direction.UP ? -90 : facing == Direction.DOWN ? 90 : 0; } 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 665ed1796..2809bf0b6 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java +++ b/src/main/java/com/simibubi/create/foundation/utility/VecHelper.java @@ -21,6 +21,7 @@ import net.minecraft.util.math.vector.Vector3i; public class VecHelper { + public static final Vector3f ZERO_3F = new Vector3f(0, 0, 0); public static final Vector3d CENTER_OF_ORIGIN = new Vector3d(.5, .5, .5); public static Vector3d rotate(Vector3d vec, Vector3d rotationVec) { diff --git a/src/main/resources/create.mixins.json b/src/main/resources/create.mixins.json index 0938f8534..3bc4de366 100644 --- a/src/main/resources/create.mixins.json +++ b/src/main/resources/create.mixins.json @@ -9,6 +9,7 @@ "client": [ "CancelTileEntityRenderMixin", "EntityContraptionInteractionMixin", + "FixNormalScalingMixin", "FogColorTrackerMixin", "HeavyBootsOnPlayerMixin", "LightUpdateMixin",