mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-29 08:27:03 +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.entity.Entity;
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.vector.Matrix4f;
|
import net.minecraft.util.math.vector.Matrix4f;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LIFETIME: one frame
|
|
||||||
*
|
|
||||||
* <p>
|
* <p>
|
||||||
* ContraptionMatrices must be re-created per-contraption per-frame
|
* ContraptionMatrices must be cleared and setup per-contraption per-frame
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public class ContraptionMatrices {
|
public class ContraptionMatrices {
|
||||||
|
|
||||||
/**
|
private final MatrixStack modelViewProjection = new MatrixStack();
|
||||||
* The results from using this are undefined.
|
private final MatrixStack viewProjection = new MatrixStack();
|
||||||
*/
|
private final MatrixStack model = new MatrixStack();
|
||||||
public static final ContraptionMatrices EMPTY = new ContraptionMatrices();
|
private final Matrix4f world = new Matrix4f();
|
||||||
|
private final Matrix4f light = new Matrix4f();
|
||||||
|
|
||||||
private final MatrixStack modelViewProjection;
|
private boolean ready;
|
||||||
private final MatrixStack viewProjection;
|
|
||||||
private final MatrixStack model;
|
|
||||||
private final Matrix4f world;
|
|
||||||
private final Matrix4f light;
|
|
||||||
|
|
||||||
private ContraptionMatrices() {
|
public ContraptionMatrices() {
|
||||||
this.viewProjection = this.model = this.modelViewProjection = new MatrixStack();
|
world.setIdentity();
|
||||||
this.world = new Matrix4f();
|
light.setIdentity();
|
||||||
this.light = new Matrix4f();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContraptionMatrices(MatrixStack viewProjection, AbstractContraptionEntity entity) {
|
public void setup(MatrixStack viewProjection, AbstractContraptionEntity entity) {
|
||||||
this.viewProjection = copyStack(viewProjection);
|
|
||||||
float partialTicks = AnimationTickHolder.getPartialTicks();
|
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();
|
modelViewProjection.pushPose();
|
||||||
getLight().multiply(this.getModel()
|
transform(modelViewProjection, viewProjection);
|
||||||
|
transform(modelViewProjection, model);
|
||||||
|
|
||||||
|
translateToEntity(world, entity, partialTicks);
|
||||||
|
|
||||||
|
light.set(world);
|
||||||
|
light.multiply(model
|
||||||
.last().pose());
|
.last().pose());
|
||||||
|
|
||||||
modelViewProjection = copyStack(viewProjection);
|
ready = true;
|
||||||
transform(getModelViewProjection(), this.getModel());
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
clearStack(modelViewProjection);
|
||||||
|
clearStack(viewProjection);
|
||||||
|
clearStack(model);
|
||||||
|
world.setIdentity();
|
||||||
|
light.setIdentity();
|
||||||
|
ready = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MatrixStack getModelViewProjection() {
|
public MatrixStack getModelViewProjection() {
|
||||||
|
@ -70,28 +78,8 @@ public class ContraptionMatrices {
|
||||||
return light;
|
return light;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matrix4f createModelViewPartial(AbstractContraptionEntity entity, float pt, Vector3d cameraPos) {
|
public boolean isReady() {
|
||||||
float x = (float) (MathHelper.lerp(pt, entity.xOld, entity.getX()) - cameraPos.x);
|
return ready;
|
||||||
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 static void transform(MatrixStack ms, MatrixStack transform) {
|
public static void transform(MatrixStack ms, MatrixStack transform) {
|
||||||
|
@ -103,11 +91,17 @@ public class ContraptionMatrices {
|
||||||
.normal());
|
.normal());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MatrixStack copyStack(MatrixStack ms) {
|
public static void translateToEntity(Matrix4f matrix, Entity entity, float partialTicks) {
|
||||||
MatrixStack cms = new MatrixStack();
|
double x = MathHelper.lerp(partialTicks, entity.xOld, entity.getX());
|
||||||
|
double y = MathHelper.lerp(partialTicks, entity.yOld, entity.getY());
|
||||||
transform(cms, ms);
|
double z = MathHelper.lerp(partialTicks, entity.zOld, entity.getZ());
|
||||||
|
matrix.setTranslation((float) x, (float) y, (float) z);
|
||||||
return cms;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void clearStack(MatrixStack ms) {
|
||||||
|
while (!ms.clear()) {
|
||||||
|
ms.popPose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class ContraptionRenderDispatcher {
|
||||||
ContraptionMatrices matrices = renderInfo.getMatrices();
|
ContraptionMatrices matrices = renderInfo.getMatrices();
|
||||||
|
|
||||||
// something went wrong with the other rendering
|
// something went wrong with the other rendering
|
||||||
if (matrices == null) return;
|
if (!matrices.isReady()) return;
|
||||||
|
|
||||||
PlacementSimulationWorld renderWorld = renderInfo.renderWorld;
|
PlacementSimulationWorld renderWorld = renderInfo.renderWorld;
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package com.simibubi.create.content.contraptions.components.structureMovement.render;
|
package com.simibubi.create.content.contraptions.components.structureMovement.render;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
|
||||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.AbstractContraptionEntity;
|
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.Contraption;
|
||||||
|
@ -11,13 +8,12 @@ import com.simibubi.create.foundation.utility.AnimationTickHolder;
|
||||||
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
|
import com.simibubi.create.foundation.utility.worldWrappers.PlacementSimulationWorld;
|
||||||
|
|
||||||
import net.minecraft.util.math.MathHelper;
|
import net.minecraft.util.math.MathHelper;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
|
||||||
|
|
||||||
public class ContraptionRenderInfo {
|
public class ContraptionRenderInfo {
|
||||||
public final Contraption contraption;
|
public final Contraption contraption;
|
||||||
public final PlacementSimulationWorld renderWorld;
|
public final PlacementSimulationWorld renderWorld;
|
||||||
|
|
||||||
private ContraptionMatrices matrices = ContraptionMatrices.EMPTY;
|
private ContraptionMatrices matrices = new ContraptionMatrices();
|
||||||
private boolean visible;
|
private boolean visible;
|
||||||
|
|
||||||
public ContraptionRenderInfo(Contraption contraption, PlacementSimulationWorld renderWorld) {
|
public ContraptionRenderInfo(Contraption contraption, PlacementSimulationWorld renderWorld) {
|
||||||
|
@ -34,7 +30,7 @@ public class ContraptionRenderInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beginFrame(BeginFrameEvent event) {
|
public void beginFrame(BeginFrameEvent event) {
|
||||||
matrices = null;
|
matrices.clear();
|
||||||
|
|
||||||
AbstractContraptionEntity entity = contraption.entity;
|
AbstractContraptionEntity entity = contraption.entity;
|
||||||
|
|
||||||
|
@ -49,7 +45,7 @@ public class ContraptionRenderInfo {
|
||||||
* Need to call this during RenderLayerEvent.
|
* Need to call this during RenderLayerEvent.
|
||||||
*/
|
*/
|
||||||
public void setupMatrices(MatrixStack viewProjection, double camX, double camY, double camZ) {
|
public void setupMatrices(MatrixStack viewProjection, double camX, double camY, double camZ) {
|
||||||
if (matrices == null) {
|
if (!matrices.isReady()) {
|
||||||
AbstractContraptionEntity entity = contraption.entity;
|
AbstractContraptionEntity entity = contraption.entity;
|
||||||
|
|
||||||
viewProjection.pushPose();
|
viewProjection.pushPose();
|
||||||
|
@ -60,14 +56,14 @@ public class ContraptionRenderInfo {
|
||||||
|
|
||||||
viewProjection.translate(x, y, z);
|
viewProjection.translate(x, y, z);
|
||||||
|
|
||||||
matrices = new ContraptionMatrices(viewProjection, entity);
|
matrices.setup(viewProjection, entity);
|
||||||
|
|
||||||
viewProjection.popPose();
|
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() {
|
public ContraptionMatrices getMatrices() {
|
||||||
return matrices;
|
return matrices;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import com.jozufozu.flywheel.core.model.IModel;
|
||||||
import com.jozufozu.flywheel.core.model.WorldModel;
|
import com.jozufozu.flywheel.core.model.WorldModel;
|
||||||
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
import com.jozufozu.flywheel.event.BeginFrameEvent;
|
||||||
import com.jozufozu.flywheel.light.GridAlignedBB;
|
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.AbstractContraptionEntity;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
import com.simibubi.create.content.contraptions.components.structureMovement.Contraption;
|
||||||
import com.simibubi.create.content.contraptions.components.structureMovement.ContraptionLighter;
|
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.tileentity.TileEntity;
|
||||||
import net.minecraft.util.math.AxisAlignedBB;
|
import net.minecraft.util.math.AxisAlignedBB;
|
||||||
import net.minecraft.util.math.BlockPos;
|
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.Matrix4f;
|
||||||
import net.minecraft.util.math.vector.Vector3d;
|
import net.minecraft.util.math.vector.Vector3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
@ -39,7 +41,8 @@ public class RenderedContraption extends ContraptionRenderInfo {
|
||||||
|
|
||||||
private final Map<RenderType, ModelRenderer> renderLayers = new HashMap<>();
|
private final Map<RenderType, ModelRenderer> renderLayers = new HashMap<>();
|
||||||
|
|
||||||
private Matrix4f modelViewPartial;
|
private final Matrix4f modelViewPartial = new Matrix4f();
|
||||||
|
private boolean modelViewPartialReady;
|
||||||
private AxisAlignedBB lightBox;
|
private AxisAlignedBB lightBox;
|
||||||
|
|
||||||
public RenderedContraption(Contraption contraption, PlacementSimulationWorld renderWorld) {
|
public RenderedContraption(Contraption contraption, PlacementSimulationWorld renderWorld) {
|
||||||
|
@ -73,20 +76,31 @@ public class RenderedContraption extends ContraptionRenderInfo {
|
||||||
public void beginFrame(BeginFrameEvent event) {
|
public void beginFrame(BeginFrameEvent event) {
|
||||||
super.beginFrame(event);
|
super.beginFrame(event);
|
||||||
|
|
||||||
|
modelViewPartial.setIdentity();
|
||||||
|
modelViewPartialReady = false;
|
||||||
|
|
||||||
if (!isVisible()) return;
|
if (!isVisible()) return;
|
||||||
|
|
||||||
kinetics.beginFrame(event.getInfo());
|
kinetics.beginFrame(event.getInfo());
|
||||||
|
|
||||||
Vector3d cameraPos = event.getCameraPos();
|
Vector3d cameraPos = event.getCameraPos();
|
||||||
|
|
||||||
modelViewPartial = ContraptionMatrices.createModelViewPartial(contraption.entity, AnimationTickHolder.getPartialTicks(), cameraPos);
|
|
||||||
|
|
||||||
lightBox = GridAlignedBB.toAABB(lighter.lightVolume.getTextureVolume())
|
lightBox = GridAlignedBB.toAABB(lighter.lightVolume.getTextureVolume())
|
||||||
.move(-cameraPos.x, -cameraPos.y, -cameraPos.z);
|
.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) {
|
void setup(ContraptionProgram shader) {
|
||||||
if (modelViewPartial == null || lightBox == null) return;
|
if (!modelViewPartialReady || lightBox == null) return;
|
||||||
shader.bind(modelViewPartial, lightBox);
|
shader.bind(modelViewPartial, lightBox);
|
||||||
lighter.lightVolume.bind();
|
lighter.lightVolume.bind();
|
||||||
}
|
}
|
||||||
|
@ -144,4 +158,13 @@ public class RenderedContraption extends ContraptionRenderInfo {
|
||||||
private void buildActors() {
|
private void buildActors() {
|
||||||
contraption.getActors().forEach(kinetics::createActor);
|
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