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.
* <p>
* <br>
* 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)
* will have their bakedModel fields populated.
* <p>
* <br>
* Attempting to create a PartialModel after ModelRegistryEvent will cause an error.
*/
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;
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) {

View file

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

View file

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

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.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<T extends TileEntity & IChestLid> extends TileEntityInstance<T> 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<T extends TileEntity & IChestLid> 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<T extends TileEntity & IChestLid> 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<T extends TileEntity & IChestLid> extends TileEntityI
body.setRotation(baseRotation);
ChestBlock chestBlock = (ChestBlock) block;
AbstractChestBlock<?> chestBlock = (AbstractChestBlock<?>) block;
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() {
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<T extends TileEntity & IChestLid> 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();
}