Correctly render chests

- Give up on quaternions
 - Lids lazily update transform matrices
 - MatrixTransformStack
This commit is contained in:
Jozufozu 2021-07-11 15:54:51 -07:00
parent 0a463da724
commit 4a27fbd438
6 changed files with 80 additions and 36 deletions

View file

@ -12,12 +12,13 @@ import net.minecraftforge.client.model.ModelLoader;
/** /**
* A helper class for loading and accessing json models. * A helper class for loading and accessing json models.
* <p> * <br>
* Creating a PartialModel will make the associated modelLocation automatically load. * 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}.
* <br>
* Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations) * Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations)
* will have their bakedModel fields populated. * will have their bakedModel fields populated.
* <p> * <br>
* Attempting to create a PartialModel after ModelRegistryEvent will cause an error. * Attempting to create a PartialModel after ModelRegistryEvent will cause an error.
*/ */
public class PartialModel { public class PartialModel {

View file

@ -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;
}
}

View file

@ -1,14 +1,13 @@
package com.jozufozu.flywheel.util.transform; package com.jozufozu.flywheel.util.transform;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Quaternion; import net.minecraft.util.math.vector.Quaternion;
import net.minecraft.util.math.vector.Vector3d; import net.minecraft.util.math.vector.Vector3d;
import net.minecraft.util.math.vector.Vector3f; import net.minecraft.util.math.vector.Vector3f;
import net.minecraft.util.math.vector.Vector3i; import net.minecraft.util.math.vector.Vector3i;
public interface TransformStack { 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); TransformStack translate(double x, double y, double z);
@ -44,11 +43,11 @@ public interface TransformStack {
} }
default TransformStack centre() { default TransformStack centre() {
return translate(center); return translate(CENTER);
} }
default TransformStack unCentre() { default TransformStack unCentre() {
return translateBack(center); return translateBack(CENTER);
} }
default TransformStack translate(Vector3i vec) { default TransformStack translate(Vector3i vec) {

View file

@ -38,8 +38,7 @@ public class Vec3 {
vec4.multiply(quat); vec4.multiply(quat);
set(vec4.getX(), vec4.getY(), vec4.getZ()); return set(vec4.getX(), vec4.getY(), vec4.getZ());
return this;
} }
public Vec3 copy() { public Vec3 copy() {
@ -50,15 +49,15 @@ public class Vec3 {
return new Vector3f(x, y, z); 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.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
return this;
} }
public Vec3 add(Vec3 v) { public Vec3 add(Vec3 v) {
add(v.x, v.y, v.z); return add(v.x, v.y, v.z);
return this;
} }
public Vec3 add(float x, float y, float z) { public Vec3 add(float x, float y, float z) {
@ -68,6 +67,10 @@ public class Vec3 {
return this; return this;
} }
public Vec3 sub(Vec3 v) {
return sub(v.x, v.y, v.z);
}
public Vec3 sub(float x, float y, float z) { public Vec3 sub(float x, float y, float z) {
this.x -= x; this.x -= x;
this.y -= y; this.y -= y;

View file

@ -28,13 +28,13 @@ public class Vec4 {
this.w = w; this.w = w;
} }
public void multiply(Quaternion quat) { public Vec4 multiply(Quaternion quat) {
Quaternion quaternion = new Quaternion(quat); Quaternion quaternion = new Quaternion(quat);
quaternion.multiply(new Quaternion(this.getX(), this.getY(), this.getZ(), 0.0F)); quaternion.multiply(new Quaternion(this.getX(), this.getY(), this.getZ(), 0.0F));
Quaternion quaternion1 = new Quaternion(quat); Quaternion quaternion1 = new Quaternion(quat);
quaternion1.conjugate(); quaternion1.conjugate();
quaternion.multiply(quaternion1); 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() { public Vec3 xyz() {
@ -57,10 +57,11 @@ public class Vec4 {
return w; 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.x = x;
this.y = y; this.y = y;
this.z = z; this.z = z;
this.w = w; this.w = w;
return this;
} }
} }

View file

@ -6,16 +6,19 @@ import com.jozufozu.flywheel.backend.instancing.tile.TileEntityInstance;
import com.jozufozu.flywheel.backend.model.BufferedModel; import com.jozufozu.flywheel.backend.model.BufferedModel;
import com.jozufozu.flywheel.core.Materials; 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.materials.OrientedData;
import com.jozufozu.flywheel.core.model.ModelPart; import com.jozufozu.flywheel.core.model.ModelPart;
import com.jozufozu.flywheel.util.AnimationTickHolder; 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.Vec3;
import com.jozufozu.flywheel.util.vec.Vec4; import com.jozufozu.flywheel.util.vec.Vec4;
import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.matrix.MatrixStack;
import it.unimi.dsi.fastutil.floats.Float2FloatFunction; import it.unimi.dsi.fastutil.floats.Float2FloatFunction;
import net.minecraft.block.AbstractChestBlock;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.ChestBlock; import net.minecraft.block.ChestBlock;
import net.minecraft.client.renderer.Atlases; import net.minecraft.client.renderer.Atlases;
@ -26,6 +29,7 @@ import net.minecraft.tileentity.IChestLid;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityMerger; import net.minecraft.tileentity.TileEntityMerger;
import net.minecraft.util.math.vector.Quaternion; 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.Vector3f;
import net.minecraft.util.math.vector.Vector4f; import net.minecraft.util.math.vector.Vector4f;
@ -36,7 +40,7 @@ import java.util.Calendar;
public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityInstance<T> implements IDynamicInstance { public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityInstance<T> implements IDynamicInstance {
private final OrientedData body; private final OrientedData body;
private final OrientedData lid; private final ModelData lid;
private final Float2FloatFunction lidProgress; private final Float2FloatFunction lidProgress;
private final RenderMaterial renderMaterial; private final RenderMaterial renderMaterial;
@ -44,6 +48,8 @@ public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityI
private final ChestType chestType; private final ChestType chestType;
private final Quaternion baseRotation; private final Quaternion baseRotation;
private float lastProgress = Float.NaN;
public ChestInstance(MaterialManager<?> materialManager, T tile) { public ChestInstance(MaterialManager<?> materialManager, T tile) {
super(materialManager, tile); super(materialManager, tile);
@ -54,11 +60,9 @@ public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityI
body = baseInstance() body = baseInstance()
.setPosition(getInstancePosition()); .setPosition(getInstancePosition());
lid = lidInstance() lid = lidInstance();
.setPosition(getInstancePosition())
.nudge(0, 9f/16f, 0);
if (block instanceof ChestBlock) { if (block instanceof AbstractChestBlock) {
// MatrixStack stack = new MatrixStack(); // MatrixStack stack = new MatrixStack();
// //
@ -69,7 +73,7 @@ public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityI
body.setRotation(baseRotation); body.setRotation(baseRotation);
ChestBlock chestBlock = (ChestBlock) block; AbstractChestBlock<?> chestBlock = (AbstractChestBlock<?>) block;
TileEntityMerger.ICallbackWrapper<? extends ChestTileEntity> wrapper = chestBlock.getBlockEntitySource(blockState, world, getWorldPosition(), true); TileEntityMerger.ICallbackWrapper<? extends ChestTileEntity> wrapper = chestBlock.getBlockEntitySource(blockState, world, getWorldPosition(), true);
@ -86,27 +90,27 @@ public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityI
public void beginFrame() { public void beginFrame() {
float progress = lidProgress.get(AnimationTickHolder.getPartialTicks()); float progress = lidProgress.get(AnimationTickHolder.getPartialTicks());
if (lastProgress == progress) return;
lastProgress = progress;
progress = 1.0F - progress; progress = 1.0F - progress;
progress = 1.0F - progress * progress * progress; progress = 1.0F - progress * progress * progress;
float angleX = -(progress * ((float) Math.PI / 2F)); float angleX = -(progress * ((float) Math.PI / 2F));
MatrixTransformStack stack = new MatrixTransformStack();
Vec3 axis = Vec3.POSITIVE_X.copy(); stack.translate(getInstancePosition())
Vec3 pivot = new Vec3(0, 0, 1f / 16f); .translate(0, 9f/16f, 0)
pivot.add(0.5f, 0.5f, 0.5f) .centre()
.multiply(baseRotation) .multiply(baseRotation)
.sub(0.5f, 0.5f, 0.5f); .unCentre()
axis.multiply(baseRotation); .translate(0, 0, 1f / 16f)
.multiply(Vector3f.POSITIVE_X.getRadialQuaternion(angleX))
.translate(0, 0, -1f / 16f);
Quaternion quaternion = new Quaternion(axis.convert(), angleX, false); lid.setTransform(stack.unwrap());
quaternion.multiply(baseRotation);
lid.setRotation(quaternion)
.setPosition(getInstancePosition())
.nudge(0, 9f/16f, 0)
.setPivot(pivot);
} }
@ -128,9 +132,9 @@ public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityI
.createInstance(); .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) .get("lid_" + renderMaterial.getTextureId(), this::getLidModel)
.createInstance(); .createInstance();
} }