mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 16:06:48 +01:00
Reuse contraption matrices
- Optimize memory usage by reusing ContraptionMatrices instances
This commit is contained in:
parent
26fbe97ae6
commit
333ef9ecbb
4 changed files with 80 additions and 67 deletions
|
@ -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
|
||||
*
|
||||
* <p>
|
||||
* ContraptionMatrices must be re-created per-contraption per-frame
|
||||
* ContraptionMatrices must be cleared and setup per-contraption per-frame
|
||||
* </p>
|
||||
*/
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<RenderType, ModelRenderer> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue