From 4a27fbd4381ee80cfc97558a546c67c13af65557 Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Sun, 11 Jul 2021 15:54:51 -0700 Subject: [PATCH] Correctly render chests - Give up on quaternions - Lids lazily update transform matrices - MatrixTransformStack --- .../jozufozu/flywheel/core/PartialModel.java | 7 +-- .../util/transform/MatrixTransformStack.java | 36 +++++++++++++++ .../util/transform/TransformStack.java | 7 ++- .../com/jozufozu/flywheel/util/vec/Vec3.java | 13 ++++-- .../com/jozufozu/flywheel/util/vec/Vec4.java | 7 +-- .../flywheel/vanilla/ChestInstance.java | 46 ++++++++++--------- 6 files changed, 80 insertions(+), 36 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java diff --git a/src/main/java/com/jozufozu/flywheel/core/PartialModel.java b/src/main/java/com/jozufozu/flywheel/core/PartialModel.java index f769f542b..198c8c8ba 100644 --- a/src/main/java/com/jozufozu/flywheel/core/PartialModel.java +++ b/src/main/java/com/jozufozu/flywheel/core/PartialModel.java @@ -12,12 +12,13 @@ import net.minecraftforge.client.model.ModelLoader; /** * A helper class for loading and accessing json models. - *

+ *
* Creating a PartialModel will make the associated modelLocation automatically load. - * As such, PartialModels must be initialized at or before {@link ModelRegistryEvent}. + * PartialModels must be initialized during {@link net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent FMLClientSetupEvent}. + *
* Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations) * will have their bakedModel fields populated. - *

+ *
* Attempting to create a PartialModel after ModelRegistryEvent will cause an error. */ public class PartialModel { diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java b/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java new file mode 100644 index 000000000..0ae2e605b --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/util/transform/MatrixTransformStack.java @@ -0,0 +1,36 @@ +package com.jozufozu.flywheel.util.transform; + +import com.mojang.blaze3d.matrix.MatrixStack; + +import net.minecraft.util.math.vector.Quaternion; + +public class MatrixTransformStack implements TransformStack { + + private final MatrixStack internal = new MatrixStack(); + + public MatrixStack unwrap() { + return internal; + } + + @Override + public TransformStack translate(double x, double y, double z) { + internal.translate(x, y, z); + return this; + } + + @Override + public TransformStack multiply(Quaternion quaternion) { + internal.multiply(quaternion); + return this; + } + + @Override + public TransformStack push() { + return this; + } + + @Override + public TransformStack pop() { + return this; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/util/transform/TransformStack.java b/src/main/java/com/jozufozu/flywheel/util/transform/TransformStack.java index 547b07c70..f50571a43 100644 --- a/src/main/java/com/jozufozu/flywheel/util/transform/TransformStack.java +++ b/src/main/java/com/jozufozu/flywheel/util/transform/TransformStack.java @@ -1,14 +1,13 @@ package com.jozufozu.flywheel.util.transform; import net.minecraft.util.Direction; -import net.minecraft.util.math.BlockPos; 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.Vector3i; public interface TransformStack { - public static final Vector3d center = new Vector3d(0.5, 0.5, 0.5); + Vector3d CENTER = new Vector3d(0.5, 0.5, 0.5); TransformStack translate(double x, double y, double z); @@ -44,11 +43,11 @@ public interface TransformStack { } default TransformStack centre() { - return translate(center); + return translate(CENTER); } default TransformStack unCentre() { - return translateBack(center); + return translateBack(CENTER); } default TransformStack translate(Vector3i vec) { diff --git a/src/main/java/com/jozufozu/flywheel/util/vec/Vec3.java b/src/main/java/com/jozufozu/flywheel/util/vec/Vec3.java index 2a7d1a8ae..d9f6f3414 100644 --- a/src/main/java/com/jozufozu/flywheel/util/vec/Vec3.java +++ b/src/main/java/com/jozufozu/flywheel/util/vec/Vec3.java @@ -38,8 +38,7 @@ public class Vec3 { vec4.multiply(quat); - set(vec4.getX(), vec4.getY(), vec4.getZ()); - return this; + return set(vec4.getX(), vec4.getY(), vec4.getZ()); } public Vec3 copy() { @@ -50,15 +49,15 @@ public class Vec3 { return new Vector3f(x, y, z); } - public void set(float x, float y, float z) { + public Vec3 set(float x, float y, float z) { this.x = x; this.y = y; this.z = z; + return this; } public Vec3 add(Vec3 v) { - add(v.x, v.y, v.z); - return this; + return add(v.x, v.y, v.z); } public Vec3 add(float x, float y, float z) { @@ -68,6 +67,10 @@ public class Vec3 { return this; } + public Vec3 sub(Vec3 v) { + return sub(v.x, v.y, v.z); + } + public Vec3 sub(float x, float y, float z) { this.x -= x; this.y -= y; diff --git a/src/main/java/com/jozufozu/flywheel/util/vec/Vec4.java b/src/main/java/com/jozufozu/flywheel/util/vec/Vec4.java index 2fed35813..668751fa9 100644 --- a/src/main/java/com/jozufozu/flywheel/util/vec/Vec4.java +++ b/src/main/java/com/jozufozu/flywheel/util/vec/Vec4.java @@ -28,13 +28,13 @@ public class Vec4 { this.w = w; } - public void multiply(Quaternion quat) { + public Vec4 multiply(Quaternion quat) { Quaternion quaternion = new Quaternion(quat); quaternion.multiply(new Quaternion(this.getX(), this.getY(), this.getZ(), 0.0F)); Quaternion quaternion1 = new Quaternion(quat); quaternion1.conjugate(); quaternion.multiply(quaternion1); - this.set(quaternion.getX(), quaternion.getY(), quaternion.getZ(), this.getW()); + return set(quaternion.getX(), quaternion.getY(), quaternion.getZ(), this.getW()); } public Vec3 xyz() { @@ -57,10 +57,11 @@ public class Vec4 { return w; } - public void set(float x, float y, float z, float w) { + public Vec4 set(float x, float y, float z, float w) { this.x = x; this.y = y; this.z = z; this.w = w; + return this; } } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index 0e63f8f9d..f8108ebdc 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -6,16 +6,19 @@ import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance; import com.jozufozu.flywheel.backend.model.BufferedModel; import com.jozufozu.flywheel.core.Materials; +import com.jozufozu.flywheel.core.materials.ModelData; import com.jozufozu.flywheel.core.materials.OrientedData; import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.util.AnimationTickHolder; +import com.jozufozu.flywheel.util.transform.MatrixTransformStack; import com.jozufozu.flywheel.util.vec.Vec3; import com.jozufozu.flywheel.util.vec.Vec4; import com.mojang.blaze3d.matrix.MatrixStack; import it.unimi.dsi.fastutil.floats.Float2FloatFunction; +import net.minecraft.block.AbstractChestBlock; import net.minecraft.block.Block; import net.minecraft.block.ChestBlock; import net.minecraft.client.renderer.Atlases; @@ -26,6 +29,7 @@ import net.minecraft.tileentity.IChestLid; import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityMerger; 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.Vector4f; @@ -36,7 +40,7 @@ import java.util.Calendar; public class ChestInstance extends TileEntityInstance implements IDynamicInstance { private final OrientedData body; - private final OrientedData lid; + private final ModelData lid; private final Float2FloatFunction lidProgress; private final RenderMaterial renderMaterial; @@ -44,6 +48,8 @@ public class ChestInstance extends TileEntityI private final ChestType chestType; private final Quaternion baseRotation; + private float lastProgress = Float.NaN; + public ChestInstance(MaterialManager materialManager, T tile) { super(materialManager, tile); @@ -54,11 +60,9 @@ public class ChestInstance extends TileEntityI body = baseInstance() .setPosition(getInstancePosition()); - lid = lidInstance() - .setPosition(getInstancePosition()) - .nudge(0, 9f/16f, 0); + lid = lidInstance(); - if (block instanceof ChestBlock) { + if (block instanceof AbstractChestBlock) { // MatrixStack stack = new MatrixStack(); // @@ -69,7 +73,7 @@ public class ChestInstance extends TileEntityI body.setRotation(baseRotation); - ChestBlock chestBlock = (ChestBlock) block; + AbstractChestBlock chestBlock = (AbstractChestBlock) block; TileEntityMerger.ICallbackWrapper wrapper = chestBlock.getBlockEntitySource(blockState, world, getWorldPosition(), true); @@ -86,27 +90,27 @@ public class ChestInstance extends TileEntityI public void beginFrame() { float progress = lidProgress.get(AnimationTickHolder.getPartialTicks()); + if (lastProgress == progress) return; + + lastProgress = progress; + progress = 1.0F - progress; progress = 1.0F - progress * progress * progress; float angleX = -(progress * ((float) Math.PI / 2F)); + MatrixTransformStack stack = new MatrixTransformStack(); - Vec3 axis = Vec3.POSITIVE_X.copy(); - Vec3 pivot = new Vec3(0, 0, 1f / 16f); - pivot.add(0.5f, 0.5f, 0.5f) + stack.translate(getInstancePosition()) + .translate(0, 9f/16f, 0) + .centre() .multiply(baseRotation) - .sub(0.5f, 0.5f, 0.5f); - axis.multiply(baseRotation); + .unCentre() + .translate(0, 0, 1f / 16f) + .multiply(Vector3f.POSITIVE_X.getRadialQuaternion(angleX)) + .translate(0, 0, -1f / 16f); - Quaternion quaternion = new Quaternion(axis.convert(), angleX, false); - - quaternion.multiply(baseRotation); - - lid.setRotation(quaternion) - .setPosition(getInstancePosition()) - .nudge(0, 9f/16f, 0) - .setPivot(pivot); + lid.setTransform(stack.unwrap()); } @@ -128,9 +132,9 @@ public class ChestInstance extends TileEntityI .createInstance(); } - private OrientedData lidInstance() { + private ModelData lidInstance() { - return materialManager.getMaterial(Materials.ORIENTED, renderMaterial.getAtlasId()) + return materialManager.getMaterial(Materials.TRANSFORMED, renderMaterial.getAtlasId()) .get("lid_" + renderMaterial.getTextureId(), this::getLidModel) .createInstance(); }