diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionMatrices.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionMatrices.java index f2c43dfeb..733ff004d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionMatrices.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionMatrices.java @@ -7,47 +7,55 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder; import net.minecraft.entity.Entity; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Matrix4f; -import net.minecraft.util.math.vector.Vector3d; /** - * LIFETIME: one frame - * *

- * ContraptionMatrices must be re-created per-contraption per-frame + * ContraptionMatrices must be cleared and setup per-contraption per-frame *

*/ public class ContraptionMatrices { - /** - * The results from using this are undefined. - */ - public static final ContraptionMatrices EMPTY = new ContraptionMatrices(); + private final MatrixStack modelViewProjection = new MatrixStack(); + private final MatrixStack viewProjection = new MatrixStack(); + private final MatrixStack model = new MatrixStack(); + private final Matrix4f world = new Matrix4f(); + private final Matrix4f light = new Matrix4f(); - private final MatrixStack modelViewProjection; - private final MatrixStack viewProjection; - private final MatrixStack model; - private final Matrix4f world; - private final Matrix4f light; + private boolean ready; - private ContraptionMatrices() { - this.viewProjection = this.model = this.modelViewProjection = new MatrixStack(); - this.world = new Matrix4f(); - this.light = new Matrix4f(); + public ContraptionMatrices() { + world.setIdentity(); + light.setIdentity(); } - public ContraptionMatrices(MatrixStack viewProjection, AbstractContraptionEntity entity) { - this.viewProjection = copyStack(viewProjection); + public void setup(MatrixStack viewProjection, AbstractContraptionEntity entity) { float partialTicks = AnimationTickHolder.getPartialTicks(); - this.model = creatModelMatrix(entity, partialTicks); - world = translateTo(entity, partialTicks); + this.viewProjection.pushPose(); + transform(this.viewProjection, viewProjection); + model.pushPose(); + entity.doLocalTransforms(partialTicks, new MatrixStack[] { model }); - light = getWorld().copy(); - getLight().multiply(this.getModel() + modelViewProjection.pushPose(); + transform(modelViewProjection, viewProjection); + transform(modelViewProjection, model); + + translateToEntity(world, entity, partialTicks); + + light.set(world); + light.multiply(model .last().pose()); - modelViewProjection = copyStack(viewProjection); - transform(getModelViewProjection(), this.getModel()); + ready = true; + } + + public void clear() { + clearStack(modelViewProjection); + clearStack(viewProjection); + clearStack(model); + world.setIdentity(); + light.setIdentity(); + ready = false; } public MatrixStack getModelViewProjection() { @@ -70,28 +78,8 @@ public class ContraptionMatrices { return light; } - public static Matrix4f createModelViewPartial(AbstractContraptionEntity entity, float pt, Vector3d cameraPos) { - float x = (float) (MathHelper.lerp(pt, entity.xOld, entity.getX()) - cameraPos.x); - float y = (float) (MathHelper.lerp(pt, entity.yOld, entity.getY()) - cameraPos.y); - float z = (float) (MathHelper.lerp(pt, entity.zOld, entity.getZ()) - cameraPos.z); - Matrix4f mat = Matrix4f.createTranslateMatrix(x, y, z); - Matrix4f modelMatrix = creatModelMatrix(entity, pt).last().pose(); - - mat.multiply(modelMatrix); - return mat; - } - - public static MatrixStack creatModelMatrix(AbstractContraptionEntity entity, float partialTicks) { - MatrixStack model = new MatrixStack(); - entity.doLocalTransforms(partialTicks, new MatrixStack[] { model}); - return model; - } - - public static Matrix4f translateTo(Entity entity, float partialTicks) { - double x = MathHelper.lerp(partialTicks, entity.xOld, entity.getX()); - double y = MathHelper.lerp(partialTicks, entity.yOld, entity.getY()); - double z = MathHelper.lerp(partialTicks, entity.zOld, entity.getZ()); - return Matrix4f.createTranslateMatrix((float) x, (float) y, (float) z); + public boolean isReady() { + return ready; } public static void transform(MatrixStack ms, MatrixStack transform) { @@ -103,11 +91,17 @@ public class ContraptionMatrices { .normal()); } - public static MatrixStack copyStack(MatrixStack ms) { - MatrixStack cms = new MatrixStack(); - - transform(cms, ms); - - return cms; + public static void translateToEntity(Matrix4f matrix, Entity entity, float partialTicks) { + double x = MathHelper.lerp(partialTicks, entity.xOld, entity.getX()); + double y = MathHelper.lerp(partialTicks, entity.yOld, entity.getY()); + double z = MathHelper.lerp(partialTicks, entity.zOld, entity.getZ()); + matrix.setTranslation((float) x, (float) y, (float) z); } + + public static void clearStack(MatrixStack ms) { + while (!ms.clear()) { + ms.popPose(); + } + } + } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java index ddcadab07..f74968039 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderDispatcher.java @@ -79,7 +79,7 @@ public class ContraptionRenderDispatcher { ContraptionMatrices matrices = renderInfo.getMatrices(); // something went wrong with the other rendering - if (matrices == null) return; + if (!matrices.isReady()) return; PlacementSimulationWorld renderWorld = renderInfo.renderWorld; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderInfo.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderInfo.java index 1000aeed2..6bc36792d 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderInfo.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/ContraptionRenderInfo.java @@ -1,9 +1,6 @@ package com.simibubi.create.content.contraptions.components.structureMovement.render; -import javax.annotation.Nullable; - import com.jozufozu.flywheel.event.BeginFrameEvent; -import com.jozufozu.flywheel.event.RenderLayerEvent; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; @@ -11,13 +8,12 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld; import net.minecraft.util.math.MathHelper; -import net.minecraft.util.math.vector.Vector3d; public class ContraptionRenderInfo { public final Contraption contraption; public final PlacementSimulationWorld renderWorld; - private ContraptionMatrices matrices = ContraptionMatrices.EMPTY; + private ContraptionMatrices matrices = new ContraptionMatrices(); private boolean visible; public ContraptionRenderInfo(Contraption contraption, PlacementSimulationWorld renderWorld) { @@ -34,7 +30,7 @@ public class ContraptionRenderInfo { } public void beginFrame(BeginFrameEvent event) { - matrices = null; + matrices.clear(); AbstractContraptionEntity entity = contraption.entity; @@ -49,7 +45,7 @@ public class ContraptionRenderInfo { * Need to call this during RenderLayerEvent. */ public void setupMatrices(MatrixStack viewProjection, double camX, double camY, double camZ) { - if (matrices == null) { + if (!matrices.isReady()) { AbstractContraptionEntity entity = contraption.entity; viewProjection.pushPose(); @@ -60,14 +56,14 @@ public class ContraptionRenderInfo { viewProjection.translate(x, y, z); - matrices = new ContraptionMatrices(viewProjection, entity); + matrices.setup(viewProjection, entity); viewProjection.popPose(); } } /** - * If #setupMatrices is called correctly, this will not return null + * If #setupMatrices is called correctly, the returned matrices will be ready */ public ContraptionMatrices getMatrices() { return matrices; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java index e33ab3422..56467c7dc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/render/RenderedContraption.java @@ -15,6 +15,7 @@ import com.jozufozu.flywheel.core.model.IModel; import com.jozufozu.flywheel.core.model.WorldModel; import com.jozufozu.flywheel.event.BeginFrameEvent; import com.jozufozu.flywheel.light.GridAlignedBB; +import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity; import com.simibubi.create.content.contraptions.components.structureMovement.Contraption; import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter; @@ -26,6 +27,7 @@ import net.minecraft.client.renderer.RenderType; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Matrix4f; import net.minecraft.util.math.vector.Vector3d; import net.minecraft.world.World; @@ -39,7 +41,8 @@ public class RenderedContraption extends ContraptionRenderInfo { private final Map renderLayers = new HashMap<>(); - private Matrix4f modelViewPartial; + private final Matrix4f modelViewPartial = new Matrix4f(); + private boolean modelViewPartialReady; private AxisAlignedBB lightBox; public RenderedContraption(Contraption contraption, PlacementSimulationWorld renderWorld) { @@ -73,20 +76,31 @@ public class RenderedContraption extends ContraptionRenderInfo { public void beginFrame(BeginFrameEvent event) { super.beginFrame(event); + modelViewPartial.setIdentity(); + modelViewPartialReady = false; + if (!isVisible()) return; kinetics.beginFrame(event.getInfo()); Vector3d cameraPos = event.getCameraPos(); - modelViewPartial = ContraptionMatrices.createModelViewPartial(contraption.entity, AnimationTickHolder.getPartialTicks(), cameraPos); - lightBox = GridAlignedBB.toAABB(lighter.lightVolume.getTextureVolume()) .move(-cameraPos.x, -cameraPos.y, -cameraPos.z); } + @Override + public void setupMatrices(MatrixStack viewProjection, double camX, double camY, double camZ) { + super.setupMatrices(viewProjection, camX, camY, camZ); + + if (!modelViewPartialReady) { + setupModelViewPartial(modelViewPartial, getMatrices().getModel().last().pose(), contraption.entity, camX, camY, camZ, AnimationTickHolder.getPartialTicks()); + modelViewPartialReady = true; + } + } + void setup(ContraptionProgram shader) { - if (modelViewPartial == null || lightBox == null) return; + if (!modelViewPartialReady || lightBox == null) return; shader.bind(modelViewPartial, lightBox); lighter.lightVolume.bind(); } @@ -144,4 +158,13 @@ public class RenderedContraption extends ContraptionRenderInfo { private void buildActors() { contraption.getActors().forEach(kinetics::createActor); } + + public static void setupModelViewPartial(Matrix4f matrix, Matrix4f modelMatrix, AbstractContraptionEntity entity, double camX, double camY, double camZ, float pt) { + float x = (float) (MathHelper.lerp(pt, entity.xOld, entity.getX()) - camX); + float y = (float) (MathHelper.lerp(pt, entity.yOld, entity.getY()) - camY); + float z = (float) (MathHelper.lerp(pt, entity.zOld, entity.getZ()) - camZ); + matrix.setTranslation(x, y, z); + matrix.multiply(modelMatrix); + } + }