Change the locks

- InstanceKey is no more.
 - InstanceData and co. keep track of removals and updates.
 - InstancedModel's buffer management is much more sane now.
 - Re-add mixin to #tickBlockEntities and ensure compat with Performant.
 - Move ...backend.instancing.impl to backend.core
This commit is contained in:
JozsefA 2021-03-30 14:14:58 -07:00
parent ff4a9e5c78
commit a2b9dfc28a
61 changed files with 466 additions and 480 deletions

View file

@ -16,10 +16,10 @@ import com.simibubi.create.content.contraptions.fluids.FluidTransportBehaviour.A
import com.simibubi.create.content.contraptions.processing.burner.BlazeBurnerBlock.HeatLevel;
import com.simibubi.create.content.contraptions.relays.belt.BeltData;
import com.simibubi.create.foundation.render.SuperByteBuffer;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.MaterialTypes;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.Lang;
@ -278,7 +278,7 @@ public class AllBlockPartials {
.unCentre();
return stack;
};
return dispatcher.getMaterial(RenderMaterials.TRANSFORMED).getModel(this, referenceState, facing, ms);
return dispatcher.getMaterial(MaterialTypes.TRANSFORMED).getModel(this, referenceState, facing, ms);
}
}

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.base;
import java.nio.ByteBuffer;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicData;
import com.simibubi.create.foundation.render.backend.core.BasicData;
import com.simibubi.create.foundation.utility.ColorHelper;
import net.minecraft.client.renderer.Vector3f;
@ -32,6 +32,7 @@ public class KineticData extends BasicData {
this.x = x;
this.y = y;
this.z = z;
markDirty();
return this;
}
@ -39,6 +40,7 @@ public class KineticData extends BasicData {
this.x += x;
this.y += y;
this.z += z;
markDirty();
return this;
}

View file

@ -4,7 +4,7 @@ import com.simibubi.create.content.contraptions.components.actors.ActorData;
import com.simibubi.create.content.contraptions.relays.belt.BeltData;
import com.simibubi.create.content.logistics.block.FlapData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.MaterialType;
import com.simibubi.create.foundation.render.backend.MaterialType;
public class KineticRenderMaterials {
public static final MaterialType<InstancedModel<RotatingData>> ROTATING = new MaterialType<>();

View file

@ -39,21 +39,20 @@ public abstract class KineticTileInstance<T extends KineticTileEntity> extends T
.setColor(tile);
}
protected final InstanceKey<RotatingData> setup(InstanceKey<RotatingData> key) {
protected final RotatingData setup(RotatingData key) {
return setup(key, getRotationAxis(), getTileSpeed());
}
protected final InstanceKey<RotatingData> setup(InstanceKey<RotatingData> key, Direction.Axis axis) {
protected final RotatingData setup(RotatingData key, Direction.Axis axis) {
return setup(key, axis, getTileSpeed());
}
protected final InstanceKey<RotatingData> setup(InstanceKey<RotatingData> key, float speed) {
protected final RotatingData setup(RotatingData key, float speed) {
return setup(key, getRotationAxis(), speed);
}
protected final InstanceKey<RotatingData> setup(InstanceKey<RotatingData> key, Direction.Axis axis, float speed) {
key.getInstance()
.setRotationAxis(axis)
protected final RotatingData setup(RotatingData key, Direction.Axis axis, float speed) {
key.setRotationAxis(axis)
.setRotationalSpeed(speed)
.setRotationOffset(getRotationOffset(axis))
.setColor(tile)

View file

@ -31,6 +31,7 @@ public class RotatingData extends KineticData {
this.rotationAxisX = (byte) (rotationAxisX * 127);
this.rotationAxisY = (byte) (rotationAxisY * 127);
this.rotationAxisZ = (byte) (rotationAxisZ * 127);
markDirty();
return this;
}

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicAttributes;
import com.simibubi.create.foundation.render.backend.core.BasicAttributes;
import net.minecraft.client.renderer.BufferBuilder;

View file

@ -1,6 +1,5 @@
package com.simibubi.create.content.contraptions.base;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
@ -8,7 +7,7 @@ import net.minecraft.block.BlockState;
public class SingleRotatingInstance extends KineticTileInstance<KineticTileEntity> {
protected final InstanceKey<RotatingData> rotatingModel;
protected final RotatingData rotatingModel;
public SingleRotatingInstance(InstancedTileRenderer<?> modelManager, KineticTileEntity tile) {
super(modelManager, tile);
@ -18,12 +17,12 @@ public class SingleRotatingInstance extends KineticTileInstance<KineticTileEntit
@Override
public void update() {
updateRotation(rotatingModel.getInstance());
updateRotation(rotatingModel);
}
@Override
public void updateLight() {
relight(pos, rotatingModel.getInstance());
relight(pos, rotatingModel);
}
@Override

View file

@ -38,26 +38,31 @@ public class ActorData extends InstanceData {
this.x = pos.getX();
this.y = pos.getY();
this.z = pos.getZ();
markDirty();
return this;
}
public ActorData setBlockLight(int blockLight) {
this.blockLight = (byte) ((blockLight & 0xF) << 4);
markDirty();
return this;
}
public ActorData setSkyLight(int skyLight) {
this.skyLight = (byte) ((skyLight & 0xF) << 4);
markDirty();
return this;
}
public ActorData setRotationOffset(float rotationOffset) {
this.rotationOffset = rotationOffset;
markDirty();
return this;
}
public ActorData setSpeed(float speed) {
this.speed = speed;
markDirty();
return this;
}
@ -70,6 +75,7 @@ public class ActorData extends InstanceData {
this.rotationAxisX = (byte) (rotationAxisX * 127);
this.rotationAxisY = (byte) (rotationAxisY * 127);
this.rotationAxisZ = (byte) (rotationAxisZ * 127);
markDirty();
return this;
}
@ -82,6 +88,7 @@ public class ActorData extends InstanceData {
this.rotationCenterX = (byte) (rotationCenterX * 127);
this.rotationCenterY = (byte) (rotationCenterY * 127);
this.rotationCenterZ = (byte) (rotationCenterZ * 127);
markDirty();
return this;
}
@ -90,6 +97,7 @@ public class ActorData extends InstanceData {
this.qY = q.getY();
this.qZ = q.getZ();
this.qW = q.getW();
markDirty();
return this;
}

View file

@ -2,8 +2,8 @@ package com.simibubi.create.content.contraptions.components.actors;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.utility.AngleHelper;
@ -12,9 +12,9 @@ import net.minecraft.block.BlockState;
import net.minecraft.client.renderer.Quaternion;
import net.minecraft.util.Direction;
public class DrillActorInstance extends com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance {
public class DrillActorInstance extends ActorInstance {
InstanceKey<ActorData> drillHead;
ActorData drillHead;
private Direction facing;
public DrillActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
@ -37,8 +37,7 @@ public class DrillActorInstance extends com.simibubi.create.content.contraptions
drillHead = renderMaterial.getModel(AllBlockPartials.DRILL_HEAD, state).createInstance();
drillHead.getInstance()
.setPosition(context.localPos)
drillHead.setPosition(context.localPos)
.setBlockLight(localBlockLight())
.setRotationOffset(0)
.setRotationAxis(0, 0, 1)
@ -48,7 +47,7 @@ public class DrillActorInstance extends com.simibubi.create.content.contraptions
@Override
public void beginFrame() {
drillHead.getInstance().setSpeed(getSpeed(facing));
drillHead.setSpeed(getSpeed(facing));
}
protected float getSpeed(Direction facing) {

View file

@ -5,10 +5,9 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
@ -25,7 +24,7 @@ public class HarvesterActorInstance extends ActorInstance {
static Vec3d rotOffset = new Vec3d(0.5f, -2 * originOffset + 0.5f, originOffset + 0.5f);
InstanceKey<ModelData> harvester;
ModelData harvester;
private Direction facing;
private float horizontalAngle;
@ -46,8 +45,7 @@ public class HarvesterActorInstance extends ActorInstance {
horizontalAngle = facing.getHorizontalAngle() + ((facing.getAxis() == Direction.Axis.X) ? 180 : 0);
harvester.getInstance()
.setBlockLight(localBlockLight());
harvester.setBlockLight(localBlockLight());
}
@Override
@ -85,7 +83,7 @@ public class HarvesterActorInstance extends ActorInstance {
.rotateX(getRotation())
.translateBack(rotOffset);
harvester.getInstance().setTransform(ms);
harvester.setTransform(ms);
}
private double getRotation() {

View file

@ -2,10 +2,9 @@ package com.simibubi.create.content.contraptions.components.crank;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.block.Block;
@ -15,7 +14,7 @@ import net.minecraft.util.Direction;
public class HandCrankInstance extends SingleRotatingInstance implements IDynamicInstance {
private final HandCrankTileEntity tile;
private InstanceKey<ModelData> crank;
private ModelData crank;
private Direction facing;
public HandCrankInstance(InstancedTileRenderer<?> modelManager, HandCrankTileEntity tile) {
@ -54,7 +53,7 @@ public class HandCrankInstance extends SingleRotatingInstance implements IDynami
.rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis), angle)
.unCentre();
crank.getInstance().setTransform(ms);
crank.setTransform(ms);
}
@Override
@ -66,6 +65,6 @@ public class HandCrankInstance extends SingleRotatingInstance implements IDynami
@Override
public void updateLight() {
super.updateLight();
if (crank != null) relight(pos, crank.getInstance());
if (crank != null) relight(pos, crank);
}
}

View file

@ -7,10 +7,9 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionKineticRenderer;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionProgram;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.*;
import net.minecraft.block.BlockState;
import net.minecraft.util.Direction;
@ -30,9 +29,9 @@ public class DeployerActorInstance extends ActorInstance {
float zRot;
float zRotPole;
InstanceKey<ModelData> pole;
InstanceKey<ModelData> hand;
InstanceKey<RotatingData> shaft;
ModelData pole;
ModelData hand;
RotatingData shaft;
public DeployerActorInstance(ContraptionKineticRenderer modelManager, MovementContext context) {
super(modelManager, context);
@ -61,13 +60,12 @@ public class DeployerActorInstance extends ActorInstance {
int blockLight = localBlockLight();
shaft.getInstance()
.setRotationAxis(axis)
shaft.setRotationAxis(axis)
.setPosition(context.localPos)
.setBlockLight(blockLight);
pole.getInstance().setBlockLight(blockLight);
hand.getInstance().setBlockLight(blockLight);
pole.setBlockLight(blockLight);
hand.setBlockLight(blockLight);
}
@Override
@ -94,7 +92,7 @@ public class DeployerActorInstance extends ActorInstance {
transformModel(msr, pole, hand, yRot, zRot, zRotPole);
}
static void transformModel(MatrixStacker msr, InstanceKey<ModelData> pole, InstanceKey<ModelData> hand, float yRot, float zRot, float zRotPole) {
static void transformModel(MatrixStacker msr, ModelData pole, ModelData hand, float yRot, float zRot, float zRotPole) {
msr.centre();
msr.rotate(Direction.SOUTH, (float) ((zRot) / 180 * Math.PI));
@ -103,11 +101,11 @@ public class DeployerActorInstance extends ActorInstance {
msr.push();
msr.rotate(Direction.SOUTH, (float) ((zRotPole) / 180 * Math.PI));
msr.unCentre();
pole.getInstance().setTransform(msr.unwrap());
pole.setTransform(msr.unwrap());
msr.pop();
msr.unCentre();
hand.getInstance().setTransform(msr.unwrap());
hand.setTransform(msr.unwrap());
}
}

View file

@ -4,7 +4,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
import com.simibubi.create.foundation.render.backend.core.OrientedData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
@ -25,9 +25,9 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance,
final float zRot;
final float zRotPole;
protected final InstanceKey<OrientedData> pole;
protected final OrientedData pole;
protected InstanceKey<OrientedData> hand;
protected OrientedData hand;
AllBlockPartials currentHand;
float progress = Float.NaN;
@ -48,7 +48,7 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance,
pole = getOrientedMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance();
updateHandPose();
relight(pos, pole.getInstance());
relight(pos, pole);
updateRotation(pole, hand, yRot, zRot, zRotPole);
@ -80,15 +80,15 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance,
float y = blockPos.getY() + ((float) facingVec.getY()) * distance;
float z = blockPos.getZ() + ((float) facingVec.getZ()) * distance;
pole.getInstance().setPosition(x, y, z);
hand.getInstance().setPosition(x, y, z);
pole.setPosition(x, y, z);
hand.setPosition(x, y, z);
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, hand.getInstance(), pole.getInstance());
relight(pos, hand, pole);
}
@Override
@ -96,8 +96,6 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance,
super.remove();
hand.delete();
pole.delete();
currentHand = null; // updateHandPose() uses an invalid key after a block update otherwise.
hand = null;
}
private boolean updateHandPose() {
@ -110,7 +108,7 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance,
hand = getOrientedMaterial().getModel(currentHand, blockState).createInstance();
relight(pos, hand.getInstance());
relight(pos, hand);
updateRotation(pole, hand, yRot, zRot, zRotPole);
return true;
@ -124,15 +122,15 @@ public class DeployerInstance extends ShaftInstance implements IDynamicInstance,
return 0;
}
static void updateRotation(InstanceKey<OrientedData> pole, InstanceKey<OrientedData> hand, float yRot, float zRot, float zRotPole) {
static void updateRotation(OrientedData pole, OrientedData hand, float yRot, float zRot, float zRotPole) {
Quaternion q = Direction.SOUTH.getUnitVector().getDegreesQuaternion(zRot);
q.multiply(Direction.UP.getUnitVector().getDegreesQuaternion(yRot));
hand.getInstance().setRotation(q);
hand.setRotation(q);
q.multiply(Direction.SOUTH.getUnitVector().getDegreesQuaternion(zRotPole));
pole.getInstance().setRotation(q);
pole.setRotation(q);
}
}

View file

@ -3,10 +3,8 @@ package com.simibubi.create.content.contraptions.components.fan;
import static net.minecraft.state.properties.BlockStateProperties.FACING;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import net.minecraft.util.Direction;
@ -15,8 +13,8 @@ import net.minecraft.util.math.MathHelper;
public class FanInstance extends KineticTileInstance<EncasedFanTileEntity> {
protected final InstanceKey<RotatingData> shaft;
protected final InstanceKey<RotatingData> fan;
protected final RotatingData shaft;
protected final RotatingData fan;
final Direction direction;
public FanInstance(InstancedTileRenderer<?> modelManager, EncasedFanTileEntity tile) {
@ -42,17 +40,17 @@ public class FanInstance extends KineticTileInstance<EncasedFanTileEntity> {
@Override
protected void update() {
updateRotation(shaft.getInstance());
updateRotation(fan.getInstance(), getFanSpeed());
updateRotation(shaft);
updateRotation(fan, getFanSpeed());
}
@Override
public void updateLight() {
BlockPos behind = pos.offset(direction.getOpposite());
relight(behind, shaft.getInstance());
relight(behind, shaft);
BlockPos inFront = pos.offset(direction);
relight(inFront, fan.getInstance());
relight(inFront, fan);
}
@Override

View file

@ -10,7 +10,7 @@ import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
@ -27,15 +27,15 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> im
protected boolean connectedLeft;
protected float connectorAngleMult;
protected final InstanceKey<RotatingData> shaft;
protected final RotatingData shaft;
protected final InstanceKey<ModelData> wheel;
protected final ModelData wheel;
protected List<InstanceKey<ModelData>> connectors;
protected InstanceKey<ModelData> upperRotating;
protected InstanceKey<ModelData> lowerRotating;
protected InstanceKey<ModelData> upperSliding;
protected InstanceKey<ModelData> lowerSliding;
protected List<ModelData> connectors;
protected ModelData upperRotating;
protected ModelData lowerRotating;
protected ModelData upperSliding;
protected ModelData lowerSliding;
protected float lastAngle = Float.NaN;
@ -100,22 +100,22 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> im
ms.push();
transformConnector(msr, true, true, rotation, connectedLeft);
upperRotating.getInstance().setTransform(ms);
upperRotating.setTransform(ms);
ms.pop();
ms.push();
transformConnector(msr, false, true, rotation, connectedLeft);
lowerRotating.getInstance().setTransform(ms);
lowerRotating.setTransform(ms);
ms.pop();
ms.push();
transformConnector(msr, true, false, rotation, connectedLeft);
upperSliding.getInstance().setTransform(ms);
upperSliding.setTransform(ms);
ms.pop();
ms.push();
transformConnector(msr, false, false, rotation, connectedLeft);
lowerSliding.getInstance().setTransform(ms);
lowerSliding.setTransform(ms);
ms.pop();
ms.pop();
@ -125,20 +125,20 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> im
.rotate(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, facing.getAxis()), AngleHelper.rad(angle))
.unCentre();
wheel.getInstance().setTransform(ms);
wheel.setTransform(ms);
}
@Override
protected void update() {
updateRotation(shaft.getInstance());
updateRotation(shaft);
}
@Override
public void updateLight() {
relight(pos, shaft.getInstance(), wheel.getInstance());
relight(pos, shaft, wheel);
if (connection != null) {
relight(this.pos.offset(connection), connectors.stream().map(InstanceKey::getInstance));
relight(this.pos.offset(connection), connectors.stream());
}
}
@ -147,7 +147,7 @@ public class FlyWheelInstance extends KineticTileInstance<FlywheelTileEntity> im
shaft.delete();
wheel.delete();
connectors.forEach(InstanceKey::delete);
connectors.forEach(InstanceData::delete);
connectors.clear();
}

View file

@ -2,10 +2,9 @@ package com.simibubi.create.content.contraptions.components.flywheel.engine;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.block.Block;
@ -14,7 +13,7 @@ import net.minecraft.util.Direction;
public class EngineInstance extends TileEntityInstance<EngineTileEntity> {
protected InstanceKey<ModelData> frame;
protected ModelData frame;
public EngineInstance(InstancedTileRenderer<?> modelManager, EngineTileEntity tile) {
super(modelManager, tile);
@ -43,8 +42,7 @@ public class EngineInstance extends TileEntityInstance<EngineTileEntity> {
.unCentre()
.translate(0, 0, -1);
this.frame.getInstance()
.setTransform(ms);
this.frame.setTransform(ms);
}
@Override
@ -54,6 +52,6 @@ public class EngineInstance extends TileEntityInstance<EngineTileEntity> {
@Override
public void updateLight() {
relight(pos, frame.getInstance());
relight(pos, frame);
}
}

View file

@ -4,15 +4,15 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.content.contraptions.base.ShaftlessCogInstance;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
import com.simibubi.create.foundation.render.backend.core.OrientedData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.util.Direction;
public class MixerInstance extends ShaftlessCogInstance implements IDynamicInstance {
private final InstanceKey<RotatingData> mixerHead;
private final InstanceKey<OrientedData> mixerPole;
private final RotatingData mixerHead;
private final OrientedData mixerPole;
private final MechanicalMixerTileEntity mixer;
public MixerInstance(InstancedTileRenderer<?> dispatcher, MechanicalMixerTileEntity tile) {
@ -22,8 +22,7 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta
mixerHead = getRotatingMaterial().getModel(AllBlockPartials.MECHANICAL_MIXER_HEAD, blockState)
.createInstance();
mixerHead.getInstance()
.setRotationAxis(Direction.Axis.Y);
mixerHead.setRotationAxis(Direction.Axis.Y);
mixerPole = getOrientedMaterial()
.getModel(AllBlockPartials.MECHANICAL_MIXER_POLE, blockState)
@ -48,15 +47,13 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta
private void transformHead(float renderedHeadOffset) {
float speed = mixer.getRenderedHeadRotationSpeed(AnimationTickHolder.getPartialTicks());
mixerHead.getInstance()
.setPosition(getInstancePosition())
mixerHead.setPosition(getInstancePosition())
.nudge(0, -renderedHeadOffset, 0)
.setRotationalSpeed(speed * 2);
}
private void transformPole(float renderedHeadOffset) {
mixerPole.getInstance()
.setPosition(getInstancePosition())
mixerPole.setPosition(getInstancePosition())
.nudge(0, -renderedHeadOffset, 0);
}
@ -68,8 +65,8 @@ public class MixerInstance extends ShaftlessCogInstance implements IDynamicInsta
public void updateLight() {
super.updateLight();
relight(pos.down(), mixerHead.getInstance());
relight(pos, mixerPole.getInstance());
relight(pos.down(), mixerHead);
relight(pos, mixerPole);
}
@Override

View file

@ -3,22 +3,17 @@ package com.simibubi.create.content.contraptions.components.press;
import net.minecraft.client.renderer.Quaternion;
import net.minecraft.client.renderer.Vector3f;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
import com.simibubi.create.foundation.render.backend.core.OrientedData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
public class PressInstance extends ShaftInstance implements IDynamicInstance {
private final InstanceKey<OrientedData> pressHead;
private final OrientedData pressHead;
private final MechanicalPressTileEntity press;
public PressInstance(InstancedTileRenderer<?> dispatcher, MechanicalPressTileEntity tile) {
@ -31,7 +26,7 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance {
Quaternion q = Vector3f.POSITIVE_Y.getDegreesQuaternion(AngleHelper.horizontalAngle(blockState.get(MechanicalPressBlock.HORIZONTAL_FACING)));
pressHead.getInstance().setRotation(q);
pressHead.setRotation(q);
transformModels();
}
@ -47,8 +42,7 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance {
private void transformModels() {
float renderedHeadOffset = getRenderedHeadOffset(press);
pressHead.getInstance()
.setPosition(getInstancePosition())
pressHead.setPosition(getInstancePosition())
.nudge(0, -renderedHeadOffset, 0);
}
@ -60,7 +54,7 @@ public class PressInstance extends ShaftInstance implements IDynamicInstance {
public void updateLight() {
super.updateLight();
relight(pos, pressHead.getInstance());
relight(pos, pressHead);
}
@Override

View file

@ -56,7 +56,7 @@ public abstract class ContraptionLighter<C extends Contraption> implements Light
}
protected GridAlignedBB contraptionBoundsToVolume(GridAlignedBB bounds) {
bounds.grow(1); // so we have at least enough data on the edges to avoid artifacts and have smooth lighting
bounds.grow(2); // so we have at least enough data on the edges to avoid artifacts and have smooth lighting
bounds.minY = Math.max(bounds.minY, 0);
bounds.maxY = Math.min(bounds.maxY, 255);

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.contraptions.components.structureMovement.ch
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
@ -18,7 +18,7 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
final boolean fakeWorld;
final int offset;
private final InstanceKey<ModelData> head;
private final ModelData head;
public StickerInstance(InstancedTileRenderer<?> modelManager, StickerTileEntity tile) {
super(modelManager, tile);
@ -58,13 +58,12 @@ public class StickerInstance extends TileEntityInstance<StickerTileEntity> imple
.unCentre()
.translate(0, (offset * offset) * 4 / 16f, 0);
head.getInstance()
.setTransform(stack);
head.setTransform(stack);
}
@Override
public void updateLight() {
relight(pos, head.getInstance());
relight(pos, head);
}
@Override

View file

@ -6,9 +6,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.Iterate;
import com.simibubi.create.foundation.utility.MatrixStacker;
@ -19,7 +18,7 @@ import net.minecraft.util.math.MathHelper;
public class GantryCarriageInstance extends ShaftInstance implements IDynamicInstance {
private final InstanceKey<ModelData> gantryCogs;
private final ModelData gantryCogs;
final Direction facing;
final Boolean alongFirst;
@ -75,7 +74,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns
.translate(0, 9 / 16f, 0)
.unCentre();
gantryCogs.getInstance().setTransform(ms);
gantryCogs.setTransform(ms);
}
static float getRotationMultiplier(Direction.Axis gantryAxis, Direction facing) {
@ -100,7 +99,7 @@ public class GantryCarriageInstance extends ShaftInstance implements IDynamicIns
@Override
public void updateLight() {
relight(pos, gantryCogs.getInstance(), rotatingModel.getInstance());
relight(pos, gantryCogs, rotatingModel);
}
@Override

View file

@ -10,11 +10,11 @@ import com.simibubi.create.content.contraptions.components.structureMovement.Mov
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapModel;
import com.simibubi.create.foundation.render.AllProgramSpecs;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.MaterialTypes;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedModel;
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedModel;
import com.simibubi.create.foundation.render.backend.core.OrientedModel;
import com.simibubi.create.foundation.render.backend.core.TransformedModel;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.util.math.BlockPos;
@ -37,8 +37,8 @@ public class ContraptionKineticRenderer extends InstancedTileRenderer<Contraptio
@Override
public void registerMaterials() {
materials.put(RenderMaterials.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, TransformedModel::new));
materials.put(RenderMaterials.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.C_ORIENTED, OrientedModel::new));
materials.put(MaterialTypes.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.C_MODEL, TransformedModel::new));
materials.put(MaterialTypes.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.C_ORIENTED, OrientedModel::new));
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.C_BELT, BeltInstancedModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.C_ROTATING, RotatingModel::new));

View file

@ -6,9 +6,8 @@ import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
@ -17,7 +16,7 @@ import net.minecraft.util.math.MathHelper;
public class FluidValveInstance extends ShaftInstance implements IDynamicInstance {
protected InstanceKey<ModelData> pointer;
protected ModelData pointer;
protected final double xRot;
protected final double yRot;
@ -64,13 +63,13 @@ public class FluidValveInstance extends ShaftInstance implements IDynamicInstanc
.rotateY(pointerRotationOffset + pointerRotation)
.unCentre();
pointer.getInstance().setTransform(ms);
pointer.setTransform(ms);
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, pointer.getInstance());
relight(pos, pointer);
}
@Override

View file

@ -31,6 +31,7 @@ public class BeltData extends KineticData {
this.qY = q.getY();
this.qZ = q.getZ();
this.qW = q.getW();
markDirty();
return this;
}
@ -44,12 +45,14 @@ public class BeltData extends KineticData {
this.minV = target.getMinV();
this.maxU = target.getMaxU();
this.maxV = target.getMaxV();
markDirty();
return this;
}
public BeltData setScrollMult(float scrollMult) {
this.scrollMult = (byte) (scrollMult * 127);
markDirty();
return this;
}

View file

@ -9,7 +9,7 @@ import com.simibubi.create.AllBlocks;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.block.render.SpriteShiftEntry;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.utility.Iterate;
@ -30,8 +30,8 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
boolean alongZ;
BeltSlope beltSlope;
Direction facing;
protected ArrayList<InstanceKey<BeltData>> keys;
protected InstanceKey<RotatingData> pulleyKey;
protected ArrayList<BeltData> keys;
protected RotatingData pulleyKey;
public BeltInstance(InstancedTileRenderer<?> modelManager, BeltTileEntity tile) {
super(modelManager, tile);
@ -78,31 +78,30 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
DyeColor color = tile.color.orElse(null);
boolean bottom = true;
for (InstanceKey<BeltData> key : keys) {
for (BeltData key : keys) {
SpriteShiftEntry spriteShiftEntry = BeltRenderer.getSpriteShiftEntry(color, diagonal, bottom);
key.getInstance()
.setScrollTexture(spriteShiftEntry)
key.setScrollTexture(spriteShiftEntry)
.setColor(tile)
.setRotationalSpeed(getScrollSpeed());
bottom = false;
}
if (pulleyKey != null) {
updateRotation(pulleyKey.getInstance());
updateRotation(pulleyKey);
}
}
@Override
public void updateLight() {
relight(pos, keys.stream().map(InstanceKey::getInstance));
relight(pos, keys.stream());
if (pulleyKey != null) relight(pos, pulleyKey.getInstance());
if (pulleyKey != null) relight(pos, pulleyKey);
}
@Override
public void remove() {
keys.forEach(InstanceKey::delete);
keys.forEach(InstanceData::delete);
keys.clear();
if (pulleyKey != null) pulleyKey.delete();
pulleyKey = null;
@ -151,7 +150,7 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
return dir;
}
private InstanceKey<BeltData> setup(InstanceKey<BeltData> key, boolean bottom, SpriteShiftEntry spriteShift) {
private BeltData setup(BeltData key, boolean bottom, SpriteShiftEntry spriteShift) {
boolean downward = beltSlope == BeltSlope.DOWNWARD;
float rotX = (!diagonal && beltSlope != BeltSlope.HORIZONTAL ? 90 : 0) + (downward ? 180 : 0) + (sideways ? 90 : 0) + (vertical && alongZ ? 180 : 0);
float rotY = facing.getHorizontalAngle() + ((diagonal ^ alongX) && !downward ? 180 : 0) + (sideways && alongZ ? 180 : 0) + (vertical && alongX ? 90 : 0);
@ -159,8 +158,7 @@ public class BeltInstance extends KineticTileInstance<BeltTileEntity> {
Quaternion q = new Quaternion(rotX, rotY, rotZ, true);
key.getInstance()
.setScrollTexture(spriteShift)
key.setScrollTexture(spriteShift)
.setScrollMult(diagonal ? 3f / 8f : 0.5f)
.setRotation(q)
.setRotationalSpeed(getScrollSpeed())

View file

@ -4,7 +4,7 @@ import com.simibubi.create.content.contraptions.base.KineticAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicAttributes;
import com.simibubi.create.foundation.render.backend.core.BasicAttributes;
import net.minecraft.client.renderer.BufferBuilder;

View file

@ -4,10 +4,9 @@ import java.util.ArrayList;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.IRotate;
import com.simibubi.create.content.contraptions.base.KineticData;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.utility.Iterate;
@ -17,7 +16,7 @@ import net.minecraft.util.Direction;
public class SplitShaftInstance extends KineticTileInstance<SplitShaftTileEntity> {
protected final ArrayList<InstanceKey<RotatingData>> keys;
protected final ArrayList<RotatingData> keys;
public SplitShaftInstance(InstancedTileRenderer<?> modelManager, SplitShaftTileEntity tile) {
super(modelManager, tile);
@ -44,18 +43,18 @@ public class SplitShaftInstance extends KineticTileInstance<SplitShaftTileEntity
Direction[] directions = Iterate.directionsInAxis(boxAxis);
for (int i : Iterate.zeroAndOne) {
updateRotation(keys.get(i).getInstance(), tile.getSpeed() * tile.getRotationSpeedModifier(directions[i]));
updateRotation(keys.get(i), tile.getSpeed() * tile.getRotationSpeedModifier(directions[i]));
}
}
@Override
public void updateLight() {
relight(pos, keys.stream().map(InstanceKey::getInstance));
relight(pos, keys.stream());
}
@Override
public void remove() {
keys.forEach(InstanceKey::delete);
keys.forEach(InstanceData::delete);
keys.clear();
}

View file

@ -4,11 +4,8 @@ import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.*;
import net.minecraft.util.Direction;
import net.minecraft.util.math.MathHelper;
@ -75,8 +72,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns
super.updateLight();
relight(pos, faces.stream()
.flatMap(Couple::stream)
.map(InstanceKey::getInstance));
.flatMap(Couple::stream));
}
@Override
@ -88,11 +84,11 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns
protected abstract InstancedModel<ModelData> getHeadModel();
private class DialFace extends Couple<InstanceKey<ModelData>> {
private class DialFace extends Couple<ModelData> {
Direction face;
public DialFace(Direction face, InstanceKey<ModelData> first, InstanceKey<ModelData> second) {
public DialFace(Direction face, ModelData first, ModelData second) {
super(first, second);
this.face = face;
}
@ -103,13 +99,13 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns
ms.push();
rotateToFace(msr);
getSecond().getInstance().setTransform(ms);
getSecond().setTransform(ms);
msr.translate(0, dialPivot, dialPivot)
.rotate(Direction.EAST, (float) (Math.PI / 2 * -progress))
.translate(0, -dialPivot, -dialPivot);
getFirst().getInstance().setTransform(ms);
getFirst().setTransform(ms);
ms.pop();
}
@ -124,7 +120,7 @@ public abstract class GaugeInstance extends ShaftInstance implements IDynamicIns
.rotate(Direction.EAST, (float) (Math.PI / 2 * -progress))
.translate(0, -dialPivot, -dialPivot);
getFirst().getInstance().setTransform(ms);
getFirst().setTransform(ms);
ms.pop();
}

View file

@ -6,7 +6,7 @@ import java.util.Map;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileInstance;
import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.utility.Iterate;
@ -18,7 +18,7 @@ import net.minecraft.world.LightType;
public class GearboxInstance extends KineticTileInstance<GearboxTileEntity> {
protected final EnumMap<Direction, InstanceKey<RotatingData>> keys;
protected final EnumMap<Direction, RotatingData> keys;
protected Direction sourceFacing;
public GearboxInstance(InstancedTileRenderer<?> modelManager, GearboxTileEntity tile) {
@ -39,10 +39,9 @@ public class GearboxInstance extends KineticTileInstance<GearboxTileEntity> {
InstancedModel<RotatingData> shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction);
InstanceKey<RotatingData> key = shaft.createInstance();
RotatingData key = shaft.createInstance();
key.getInstance()
.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
key.setRotationAxis(Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getUnitVector())
.setRotationalSpeed(getSpeed(direction))
.setRotationOffset(getRotationOffset(axis)).setColor(tile)
.setPosition(getInstancePosition())
@ -77,22 +76,22 @@ public class GearboxInstance extends KineticTileInstance<GearboxTileEntity> {
@Override
public void update() {
updateSourceFacing();
for (Map.Entry<Direction, InstanceKey<RotatingData>> key : keys.entrySet()) {
for (Map.Entry<Direction, RotatingData> key : keys.entrySet()) {
Direction direction = key.getKey();
Direction.Axis axis = direction.getAxis();
updateRotation(key.getValue().getInstance(), axis, getSpeed(direction));
updateRotation(key.getValue(), axis, getSpeed(direction));
}
}
@Override
public void updateLight() {
relight(pos, keys.values().stream().map(InstanceKey::getInstance));
relight(pos, keys.values().stream());
}
@Override
public void remove() {
keys.values().forEach(InstanceKey::delete);
keys.values().forEach(InstanceData::delete);
keys.clear();
}
}

View file

@ -2,7 +2,7 @@ package com.simibubi.create.content.logistics.block;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight;
import com.simibubi.create.foundation.render.backend.core.IFlatLight;
import net.minecraft.client.renderer.Vector3f;
import net.minecraft.util.math.BlockPos;
@ -54,18 +54,21 @@ public class FlapData extends InstanceData implements IFlatLight<FlapData> {
this.x = x;
this.y = y;
this.z = z;
markDirty();
return this;
}
@Override
public FlapData setBlockLight(int blockLight) {
this.blockLight = (byte) ((blockLight & 0xF) << 4);
markDirty();
return this;
}
@Override
public FlapData setSkyLight(int skyLight) {
this.skyLight = (byte) ((skyLight & 0xF) << 4);
markDirty();
return this;
}
@ -73,26 +76,31 @@ public class FlapData extends InstanceData implements IFlatLight<FlapData> {
this.segmentOffsetX = x;
this.segmentOffsetY = y;
this.segmentOffsetZ = z;
markDirty();
return this;
}
public FlapData setIntensity(float intensity) {
this.intensity = intensity;
markDirty();
return this;
}
public FlapData setHorizontalAngle(float horizontalAngle) {
this.horizontalAngle = horizontalAngle;
markDirty();
return this;
}
public FlapData setFlapScale(float flapScale) {
this.flapScale = flapScale;
markDirty();
return this;
}
public FlapData setFlapness(float flapness) {
this.flapness = flapness;
markDirty();
return this;
}
@ -100,6 +108,7 @@ public class FlapData extends InstanceData implements IFlatLight<FlapData> {
pivotX = x / 16f;
pivotY = y / 16f;
pivotZ = z / 16f;
markDirty();
return this;
}

View file

@ -9,11 +9,7 @@ import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
import com.simibubi.create.content.logistics.block.FlapData;
import com.simibubi.create.foundation.gui.widgets.InterpolatedValue;
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.TileEntityInstance;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.util.Direction;
@ -21,7 +17,7 @@ import net.minecraft.world.LightType;
public class BeltTunnelInstance extends TileEntityInstance<BeltTunnelTileEntity> implements IDynamicInstance {
private final Map<Direction, ArrayList<InstanceKey<FlapData>>> tunnelFlaps;
private final Map<Direction, ArrayList<FlapData>> tunnelFlaps;
public BeltTunnelInstance(InstancedTileRenderer<?> modelManager, BeltTunnelTileEntity tile) {
super(modelManager, tile);
@ -42,16 +38,15 @@ public class BeltTunnelInstance extends TileEntityInstance<BeltTunnelTileEntity>
float flapScale = direction.getAxis() == Direction.Axis.X ? 1 : -1;
ArrayList<InstanceKey<FlapData>> flaps = new ArrayList<>(4);
ArrayList<FlapData> flaps = new ArrayList<>(4);
for (int segment = 0; segment <= 3; segment++) {
float intensity = segment == 3 ? 1.5f : segment + 1;
float segmentOffset = -3 / 16f * segment;
InstanceKey<FlapData> key = model.createInstance();
FlapData key = model.createInstance();
key.getInstance()
.setPosition(pos)
key.setPosition(pos)
.setSegmentOffset(segmentOffset, 0, 0)
.setBlockLight(blockLight)
.setSkyLight(skyLight)
@ -82,23 +77,15 @@ public class BeltTunnelInstance extends TileEntityInstance<BeltTunnelTileEntity>
}
float flapness = flapValue.get(AnimationTickHolder.getPartialTicks());
for (InstanceKey<FlapData> key : keys) {
key.getInstance().setFlapness(flapness);
for (FlapData flap : keys) {
flap.setFlapness(flapness);
}
});
}
@Override
public void updateLight() {
int blockLight = world.getLightLevel(LightType.BLOCK, pos);
int skyLight = world.getLightLevel(LightType.SKY, pos);
for (ArrayList<InstanceKey<FlapData>> instanceKeys : tunnelFlaps.values()) {
for (InstanceKey<FlapData> it : instanceKeys) {
it.getInstance().setBlockLight(blockLight)
.setSkyLight(skyLight);
}
}
relight(pos, tunnelFlaps.values().stream().flatMap(Collection::stream));
}
@Override
@ -106,6 +93,6 @@ public class BeltTunnelInstance extends TileEntityInstance<BeltTunnelTileEntity>
tunnelFlaps.values()
.stream()
.flatMap(Collection::stream)
.forEach(InstanceKey::delete);
.forEach(InstanceData::delete);
}
}

View file

@ -4,12 +4,10 @@ import net.minecraft.util.math.MathHelper;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance;
import com.simibubi.create.foundation.render.backend.instancing.IDynamicInstance;
import com.simibubi.create.foundation.render.backend.instancing.InstanceKey;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
@ -17,7 +15,7 @@ public class EjectorInstance extends ShaftInstance implements IDynamicInstance {
protected final EjectorTileEntity tile;
protected final InstanceKey<ModelData> plate;
protected final ModelData plate;
private float lastProgress = Float.NaN;
@ -43,7 +41,7 @@ public class EjectorInstance extends ShaftInstance implements IDynamicInstance {
@Override
public void updateLight() {
super.updateLight();
relight(pos, plate.getInstance());
relight(pos, plate);
}
@Override
@ -67,6 +65,6 @@ public class EjectorInstance extends ShaftInstance implements IDynamicInstance {
EjectorRenderer.applyLidAngle(tile, angle, MatrixStacker.of(ms).translate(getInstancePosition()));
plate.getInstance().setTransform(ms);
plate.setTransform(ms);
}
}

View file

@ -3,13 +3,13 @@ package com.simibubi.create.content.logistics.block.diodes;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.MatrixStacker;
public class AdjustableRepeaterInstance extends TileEntityInstance<AdjustableRepeaterTileEntity> implements ITickableInstance {
protected final InstanceKey<ModelData> indicator;
protected final ModelData indicator;
protected int previousState;
@ -21,7 +21,7 @@ public class AdjustableRepeaterInstance extends TileEntityInstance<AdjustableRep
MatrixStack ms = new MatrixStack();
MatrixStacker.of(ms).translate(getInstancePosition());
indicator.getInstance()
indicator
.setTransform(ms)
.setColor(getColor());
@ -32,14 +32,14 @@ public class AdjustableRepeaterInstance extends TileEntityInstance<AdjustableRep
public void tick() {
if (previousState == tile.state) return;
indicator.getInstance().setColor(getColor());
indicator.setColor(getColor());
previousState = tile.state;
}
@Override
public void updateLight() {
relight(pos, indicator.getInstance());
relight(pos, indicator);
}
@Override

View file

@ -12,7 +12,7 @@ import java.util.ArrayList;
public class FunnelInstance extends TileEntityInstance<FunnelTileEntity> implements IDynamicInstance {
private final ArrayList<InstanceKey<FlapData>> flaps;
private final ArrayList<FlapData> flaps;
public FunnelInstance(InstancedTileRenderer<?> modelManager, FunnelTileEntity tile) {
super(modelManager, tile);
@ -38,10 +38,9 @@ public class FunnelInstance extends TileEntityInstance<FunnelTileEntity> impleme
float intensity = segment == 3 ? 1.5f : segment + 1;
float segmentOffset = -3 / 16f * segment;
InstanceKey<FlapData> key = model.createInstance();
FlapData key = model.createInstance();
key.getInstance()
.setPosition(pos)
key.setPosition(pos)
.setSegmentOffset(segmentOffset, 0, -tile.getFlapOffset())
.setBlockLight(blockLight)
.setSkyLight(skyLight)
@ -61,21 +60,21 @@ public class FunnelInstance extends TileEntityInstance<FunnelTileEntity> impleme
float flapness = tile.flap.get(AnimationTickHolder.getPartialTicks());
for (InstanceKey<FlapData> key : flaps) {
key.getInstance().setFlapness(flapness);
for (FlapData flap : flaps) {
flap.setFlapness(flapness);
}
}
@Override
public void updateLight() {
if (flaps != null)
relight(pos, flaps.stream().map(InstanceKey::getInstance));
relight(pos, flaps.stream());
}
@Override
public void remove() {
if (flaps == null) return;
flaps.forEach(InstanceKey::delete);
flaps.forEach(InstanceData::delete);
}
}

View file

@ -7,7 +7,7 @@ import com.simibubi.create.content.contraptions.base.RotatingData;
import com.simibubi.create.content.contraptions.base.SingleRotatingInstance;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ColorHelper;
import com.simibubi.create.foundation.utility.Iterate;
@ -22,14 +22,14 @@ import java.util.ArrayList;
public class ArmInstance extends SingleRotatingInstance implements IDynamicInstance {
final InstanceKey<ModelData> base;
final InstanceKey<ModelData> lowerBody;
final InstanceKey<ModelData> upperBody;
final InstanceKey<ModelData> head;
final InstanceKey<ModelData> claw;
private final ArrayList<InstanceKey<ModelData>> clawGrips;
final ModelData base;
final ModelData lowerBody;
final ModelData upperBody;
final ModelData head;
final ModelData claw;
private final ArrayList<ModelData> clawGrips;
private final ArrayList<InstanceKey<ModelData>> models;
private final ArrayList<ModelData> models;
private final ArmTileEntity arm;
private boolean firstTick = true;
@ -46,8 +46,8 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta
claw = mat.getModel(AllBlockPartials.ARM_CLAW_BASE, blockState).createInstance();
InstancedModel<ModelData> clawHalfModel = mat.getModel(AllBlockPartials.ARM_CLAW_GRIP, blockState);
InstanceKey<ModelData> clawGrip1 = clawHalfModel.createInstance();
InstanceKey<ModelData> clawGrip2 = clawHalfModel.createInstance();
ModelData clawGrip1 = clawHalfModel.createInstance();
ModelData clawGrip2 = clawHalfModel.createInstance();
clawGrips = Lists.newArrayList(clawGrip1, clawGrip2);
models = Lists.newArrayList(base, lowerBody, upperBody, head, claw, clawGrip1, clawGrip2);
@ -96,26 +96,21 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta
msr.rotateX(180);
ArmRenderer.transformBase(msr, baseAngle);
base.getInstance()
.setTransform(msLocal);
base.setTransform(msLocal);
ArmRenderer.transformLowerArm(msr, lowerArmAngle);
lowerBody.getInstance()
.setTransform(msLocal)
lowerBody.setTransform(msLocal)
.setColor(color);
ArmRenderer.transformUpperArm(msr, upperArmAngle);
upperBody.getInstance()
.setTransform(msLocal)
upperBody.setTransform(msLocal)
.setColor(color);
ArmRenderer.transformHead(msr, headAngle);
head.getInstance()
.setTransform(msLocal);
head.setTransform(msLocal);
ArmRenderer.transformClaw(msr);
claw.getInstance()
.setTransform(msLocal);
claw.setTransform(msLocal);
ItemStack item = this.arm.heldItem;
ItemRenderer itemRenderer = Minecraft.getInstance()
@ -129,9 +124,7 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta
msLocal.push();
int flip = index * 2 - 1;
ArmRenderer.transformClawHalf(msr, hasItem, isBlockItem, flip);
clawGrips.get(index)
.getInstance()
.setTransform(msLocal);
clawGrips.get(index).setTransform(msLocal);
msLocal.pop();
}
}
@ -140,7 +133,7 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta
public void updateLight() {
super.updateLight();
relight(pos, models.stream().map(InstanceKey::getInstance));
relight(pos, models.stream());
}
@Override
@ -151,6 +144,6 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta
@Override
public void remove() {
super.remove();
models.forEach(InstanceKey::delete);
models.forEach(InstanceData::delete);
}
}

View file

@ -3,7 +3,7 @@ package com.simibubi.create.content.logistics.block.redstone;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.ColorHelper;
@ -13,8 +13,8 @@ import net.minecraft.util.Direction;
public class AnalogLeverInstance extends TileEntityInstance<AnalogLeverTileEntity> implements IDynamicInstance {
protected final InstanceKey<ModelData> handle;
protected final InstanceKey<ModelData> indicator;
protected final ModelData handle;
protected final ModelData indicator;
final float rX;
final float rY;
@ -50,8 +50,7 @@ public class AnalogLeverInstance extends TileEntityInstance<AnalogLeverTileEntit
float state = tile.clientState.get(AnimationTickHolder.getPartialTicks());
int color = ColorHelper.mixColors(0x2C0300, 0xCD0000, state / 15f);
indicator.getInstance()
.setTransform(ms)
indicator.setTransform(ms)
.setColor(color);
float angle = (float) ((state / 15) * 90 / 180 * Math.PI);
@ -59,8 +58,7 @@ public class AnalogLeverInstance extends TileEntityInstance<AnalogLeverTileEntit
.rotate(Direction.EAST, angle)
.translate(-1 / 2f, -1 / 16f, -1 / 2f);
handle.getInstance()
.setTransform(ms);
handle.setTransform(ms);
}
@Override
@ -71,7 +69,7 @@ public class AnalogLeverInstance extends TileEntityInstance<AnalogLeverTileEntit
@Override
public void updateLight() {
relight(pos, handle.getInstance(), indicator.getInstance());
relight(pos, handle, indicator);
}
private void transform(MatrixStacker msr) {

View file

@ -3,15 +3,15 @@ package com.simibubi.create.content.schematics.block;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.foundation.render.backend.instancing.*;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.MatrixStacker;
import net.minecraft.util.Direction;
public class SchematicannonInstance extends TileEntityInstance<SchematicannonTileEntity> implements IDynamicInstance {
private final InstanceKey<ModelData> connector;
private final InstanceKey<ModelData> pipe;
private final ModelData connector;
private final ModelData pipe;
public SchematicannonInstance(InstancedTileRenderer<?> modelManager, SchematicannonTileEntity tile) {
super(modelManager, tile);
@ -44,7 +44,7 @@ public class SchematicannonInstance extends TileEntityInstance<SchematicannonTil
msr.centre();
msr.rotate(Direction.UP, (float) ((yaw + 90) / 180 * Math.PI));
msr.unCentre();
connector.getInstance().setTransform(ms);
connector.setTransform(ms);
ms.pop();
msr.translate(.5f, 15 / 16f, .5f);
@ -53,7 +53,7 @@ public class SchematicannonInstance extends TileEntityInstance<SchematicannonTil
msr.translate(-.5f, -15 / 16f, -.5f);
msr.translate(0, -recoil / 100, 0);
pipe.getInstance().setTransform(ms);
pipe.setTransform(ms);
}
@Override
@ -64,6 +64,6 @@ public class SchematicannonInstance extends TileEntityInstance<SchematicannonTil
@Override
public void updateLight() {
relight(pos, connector.getInstance(), pipe.getInstance());
relight(pos, connector, pipe);
}
}

View file

@ -1,29 +0,0 @@
package com.simibubi.create.foundation.mixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.simibubi.create.CreateClient;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
@Mixin(World.class)
public class TileAddMixin {
@Shadow @Final public boolean isRemote;
@Inject(at = @At("TAIL"), method = "addTileEntity")
private void onAddTile(TileEntity te, CallbackInfoReturnable<Boolean> cir) {
if (isRemote) {
CreateClient.kineticRenderer.get((World)(Object) this).queueAdd(te);
}
}
}

View file

@ -0,0 +1,54 @@
package com.simibubi.create.foundation.mixin;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.simibubi.create.CreateClient;
import com.simibubi.create.foundation.render.KineticRenderer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import java.util.Set;
@OnlyIn(Dist.CLIENT)
@Mixin(value = World.class, priority = 1100) // this and create.mixins.json have high priority to load after Performant
public class TileWorldHookMixin {
final World self = (World) (Object) this;
@Shadow @Final public boolean isRemote;
@Shadow @Final protected Set<TileEntity> tileEntitiesToBeRemoved;
@Inject(at = @At("TAIL"), method = "addTileEntity")
private void onAddTile(TileEntity te, CallbackInfoReturnable<Boolean> cir) {
if (isRemote) {
CreateClient.kineticRenderer.get(self).queueAdd(te);
}
}
/**
* Without this we don't unload instances when a chunk unloads.
*/
@Inject(at = @At(
value = "INVOKE",
target = "Ljava/util/Set;clear()V", ordinal = 0
),
method = "tickBlockEntities")
private void onChunkUnload(CallbackInfo ci) {
if (isRemote) {
KineticRenderer kineticRenderer = CreateClient.kineticRenderer.get(self);
for (TileEntity tile : tileEntitiesToBeRemoved) {
kineticRenderer.remove(tile);
}
}
}
}

View file

@ -11,10 +11,10 @@ import com.simibubi.create.content.contraptions.components.structureMovement.ren
import com.simibubi.create.content.contraptions.relays.belt.BeltAttributes;
import com.simibubi.create.content.logistics.block.FlapAttributes;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
import com.simibubi.create.foundation.render.backend.instancing.impl.BasicAttributes;
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformAttributes;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelAttributes;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedAttributes;
import com.simibubi.create.foundation.render.backend.core.BasicAttributes;
import com.simibubi.create.foundation.render.backend.core.TransformAttributes;
import com.simibubi.create.foundation.render.backend.core.ModelAttributes;
import com.simibubi.create.foundation.render.backend.core.OrientedAttributes;
import com.simibubi.create.foundation.render.backend.gl.shader.ProgramSpec;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderConstants;

View file

@ -6,14 +6,14 @@ import com.simibubi.create.content.contraptions.base.KineticRenderMaterials;
import com.simibubi.create.content.contraptions.base.RotatingModel;
import com.simibubi.create.content.contraptions.relays.belt.BeltInstancedModel;
import com.simibubi.create.content.logistics.block.FlapModel;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.MaterialTypes;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer;
import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedModel;
import com.simibubi.create.foundation.render.backend.instancing.impl.TransformedModel;
import com.simibubi.create.foundation.render.backend.core.OrientedModel;
import com.simibubi.create.foundation.render.backend.core.TransformedModel;
import net.minecraft.client.renderer.ActiveRenderInfo;
import net.minecraft.client.renderer.Matrix4f;
@ -29,8 +29,8 @@ public class KineticRenderer extends InstancedTileRenderer<BasicProgram> {
@Override
public void registerMaterials() {
materials.put(RenderMaterials.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.MODEL, TransformedModel::new));
materials.put(RenderMaterials.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.ORIENTED, OrientedModel::new));
materials.put(MaterialTypes.TRANSFORMED, new RenderMaterial<>(this, AllProgramSpecs.MODEL, TransformedModel::new));
materials.put(MaterialTypes.ORIENTED, new RenderMaterial<>(this, AllProgramSpecs.ORIENTED, OrientedModel::new));
materials.put(KineticRenderMaterials.BELTS, new RenderMaterial<>(this, AllProgramSpecs.BELT, BeltInstancedModel::new));
materials.put(KineticRenderMaterials.ROTATING, new RenderMaterial<>(this, AllProgramSpecs.ROTATING, RotatingModel::new));

View file

@ -0,0 +1,11 @@
package com.simibubi.create.foundation.render.backend;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
public class MaterialType<M extends InstancedModel<?>> {
@Override
public int hashCode() {
return super.hashCode() * 31 * 493286711;
}
}

View file

@ -1,11 +1,10 @@
package com.simibubi.create.foundation.render.backend;
import com.simibubi.create.foundation.render.backend.instancing.MaterialType;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.render.backend.core.OrientedData;
public class RenderMaterials {
public class MaterialTypes {
public static final MaterialType<InstancedModel<ModelData>> TRANSFORMED = new MaterialType<>();
public static final MaterialType<InstancedModel<OrientedData>> ORIENTED = new MaterialType<>();
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import java.nio.ByteBuffer;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;
@ -21,12 +21,14 @@ public class BasicData extends InstanceData implements IFlatLight<BasicData> {
@Override
public BasicData setBlockLight(int blockLight) {
this.blockLight = (byte) (blockLight << 4);
markDirty();
return this;
}
@Override
public BasicData setSkyLight(int skyLight) {
this.skyLight = (byte) (skyLight << 4);
markDirty();
return this;
}
@ -55,6 +57,7 @@ public class BasicData extends InstanceData implements IFlatLight<BasicData> {
this.r = r;
this.g = g;
this.b = b;
markDirty();
return this;
}
@ -63,6 +66,7 @@ public class BasicData extends InstanceData implements IFlatLight<BasicData> {
this.g = g;
this.b = b;
this.a = a;
markDirty();
return this;
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import com.simibubi.create.foundation.render.backend.instancing.InstanceData;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import com.mojang.blaze3d.matrix.MatrixStack;
import com.simibubi.create.foundation.render.backend.RenderUtil;
@ -17,6 +17,7 @@ public class ModelData extends BasicData {
public ModelData setTransform(MatrixStack stack) {
matrices = RenderUtil.writeMatrixStack(stack);
markDirty();
return this;
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import com.simibubi.create.foundation.render.backend.gl.attrib.CommonAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import net.minecraft.client.renderer.Quaternion;
import net.minecraft.client.renderer.Vector3f;
@ -39,6 +39,7 @@ public class OrientedData extends BasicData {
this.posX = x;
this.posY = y;
this.posZ = z;
markDirty();
return this;
}
@ -46,6 +47,7 @@ public class OrientedData extends BasicData {
this.posX += x;
this.posY += y;
this.posZ += z;
markDirty();
return this;
}
@ -61,6 +63,7 @@ public class OrientedData extends BasicData {
this.pivotX = x;
this.pivotY = y;
this.pivotZ = z;
markDirty();
return this;
}
@ -73,6 +76,7 @@ public class OrientedData extends BasicData {
this.qY = y;
this.qZ = z;
this.qW = w;
markDirty();
return this;
}

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import net.minecraft.client.renderer.BufferBuilder;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import com.simibubi.create.foundation.render.backend.gl.attrib.IAttribSpec;
import com.simibubi.create.foundation.render.backend.gl.attrib.IVertexAttrib;

View file

@ -1,4 +1,4 @@
package com.simibubi.create.foundation.render.backend.instancing.impl;
package com.simibubi.create.foundation.render.backend.core;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
import com.simibubi.create.foundation.render.backend.instancing.InstancedModel;

View file

@ -18,7 +18,7 @@ public enum MapBuffer implements GlVersioned {
@Override
public void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload) {
ByteBuffer buffer = GL30.glMapBufferRange(target, offset, length, GL30.GL_MAP_WRITE_BIT | GL30.GL_MAP_INVALIDATE_RANGE_BIT);
ByteBuffer buffer = GL30.glMapBufferRange(target, offset, length, GL30.GL_MAP_WRITE_BIT);
upload.accept(buffer);
buffer.rewind();
@ -34,7 +34,7 @@ public enum MapBuffer implements GlVersioned {
@Override
public void mapBuffer(int target, int offset, int length, Consumer<ByteBuffer> upload) {
ByteBuffer buffer = ARBMapBufferRange.glMapBufferRange(target, offset, length, GL30.GL_MAP_WRITE_BIT | GL30.GL_MAP_INVALIDATE_RANGE_BIT);
ByteBuffer buffer = ARBMapBufferRange.glMapBufferRange(target, offset, length, GL30.GL_MAP_WRITE_BIT);
upload.accept(buffer);
buffer.rewind();

View file

@ -6,12 +6,25 @@ public abstract class InstanceData {
protected final InstancedModel<?> owner;
boolean dirty;
boolean removed;
protected InstanceData(InstancedModel<?> owner) {
this.owner = owner;
}
public abstract void write(ByteBuffer buf);
public void markDirty() {
owner.anyToUpdate = true;
dirty = true;
}
public void delete() {
owner.anyToRemove = true;
removed = true;
}
public void putVec4(ByteBuffer buf, float x, float y, float z, float w) {
put(buf, x);
put(buf, y);

View file

@ -1,29 +0,0 @@
package com.simibubi.create.foundation.render.backend.instancing;
public class InstanceKey<D extends InstanceData> {
public static final int INVALID = -1;
InstancedModel<D> model;
int index;
public InstanceKey(InstancedModel<D> model, int index) {
this.model = model;
this.index = index;
}
void invalidate() {
index = INVALID;
}
public boolean isValid() {
return index != INVALID;
}
public D getInstance() {
return model.getInstance(this);
}
public void delete() {
model.deleteInstance(this);
}
}

View file

@ -5,7 +5,6 @@ import java.nio.ByteBuffer;
import java.util.*;
import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.RenderUtil;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
@ -13,7 +12,7 @@ import org.lwjgl.opengl.GL20;
import com.simibubi.create.foundation.render.backend.BufferedModel;
import com.simibubi.create.foundation.render.backend.gl.GlBuffer;
import com.simibubi.create.foundation.render.backend.gl.GlVertexArray;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelAttributes;
import com.simibubi.create.foundation.render.backend.core.ModelAttributes;
import com.simibubi.create.foundation.render.backend.gl.attrib.VertexFormat;
import net.minecraft.client.renderer.BufferBuilder;
@ -28,12 +27,10 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
protected int glBufferSize = -1;
protected int glInstanceCount = 0;
protected final ArrayList<InstanceKey<D>> keys = new ArrayList<>();
protected final ArrayList<D> data = new ArrayList<>();
protected int minIndexChanged = -1;
protected int maxIndexChanged = -1;
protected boolean anyToRemove;
boolean anyToRemove;
boolean anyToUpdate;
public InstancedModel(InstancedTileRenderer<?> renderer, BufferBuilder buf) {
super(buf);
@ -63,39 +60,19 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
}
protected void deleteInternal() {
keys.forEach(InstanceKey::invalidate);
super.deleteInternal();
instanceVBO.delete();
vao.delete();
}
public synchronized void deleteInstance(InstanceKey<D> key) {
verifyKey(key);
key.invalidate();
anyToRemove = true;
}
public D getInstance(InstanceKey<D> key) {
verifyKey(key);
markIndexChanged(key.index);
return this.data.get(key.index);
}
public synchronized InstanceKey<D> createInstance() {
public synchronized D createInstance() {
D instanceData = newInstance();
InstanceKey<D> key = new InstanceKey<>(this, data.size());
instanceData.dirty = true;
anyToUpdate = true;
data.add(instanceData);
keys.add(key);
markIndexChanged(key.index);
return key;
return instanceData;
}
protected abstract D newInstance();
@ -103,133 +80,153 @@ public abstract class InstancedModel<D extends InstanceData> extends BufferedMod
protected void doRender() {
vao.with(vao -> {
renderSetup();
Backend.compat.drawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
if (glInstanceCount > 0)
Backend.compat.drawArraysInstanced(GL11.GL_QUADS, 0, vertexCount, glInstanceCount);
});
}
protected void renderSetup() {
boolean anyRemoved = doRemoval();
if (anyToRemove) {
removeDeletedInstances();
}
if (!anyRemoved && (minIndexChanged < 0 || data.isEmpty())) return;
instanceVBO.bind();
if (!realloc()) {
VertexFormat instanceFormat = getInstanceFormat();
int stride = instanceFormat.getStride();
int newInstanceCount = instanceCount();
int instanceSize = RenderUtil.nextPowerOf2((newInstanceCount + 1) * stride);
instanceVBO.with(vbo -> {
// this probably changes enough that it's not worth reallocating the entire buffer every time.
if (instanceSize > glBufferSize) {
GL15.glBufferData(vbo.getBufferType(), instanceSize, GL15.GL_STATIC_DRAW);
glBufferSize = instanceSize;
minIndexChanged = 0;
maxIndexChanged = newInstanceCount - 1;
if (anyToRemove) {
clearBufferTail();
}
int offset = minIndexChanged * stride;
int length = (1 + maxIndexChanged - minIndexChanged) * stride;
if (length > 0) {
vbo.map(offset, length, buffer -> {
for (int i = minIndexChanged; i <= maxIndexChanged; i++) {
data.get(i).write(buffer);
}
});
if (anyToUpdate) {
updateBuffer();
}
if (newInstanceCount < glInstanceCount) {
int clearFrom = (maxIndexChanged + 1) * stride;
int clearTo = (glInstanceCount) * stride;
vbo.map(clearFrom, clearTo - clearFrom, buffer -> {
for (int i = clearFrom; i < clearTo; i++) {
buffer.put((byte) 0);
}
});
}
}
glInstanceCount = newInstanceCount;
glInstanceCount = data.size();
informAttribDivisors();
instanceVBO.unbind();
int staticAttributes = getModelFormat().getShaderAttributeCount();
instanceFormat.vertexAttribPointers(staticAttributes);
for (int i = 0; i < instanceFormat.getShaderAttributeCount(); i++) {
Backend.compat.vertexAttribDivisor(i + staticAttributes, 1);
}
});
minIndexChanged = -1;
maxIndexChanged = -1;
this.anyToRemove = false;
this.anyToUpdate = false;
}
// copied from ArrayList#removeIf
protected boolean doRemoval() {
if (!anyToRemove) return false;
private void informAttribDivisors() {
int staticAttributes = getModelFormat().getShaderAttributeCount();
getInstanceFormat().vertexAttribPointers(staticAttributes);
for (int i = 0; i < getInstanceFormat().getShaderAttributeCount(); i++) {
Backend.compat.vertexAttribDivisor(i + staticAttributes, 1);
}
}
private void clearBufferTail() {
int size = data.size();
final int offset = size * getInstanceFormat().getStride();
final int length = glBufferSize - offset;
if (length > 0) {
instanceVBO.map(offset, length, buffer -> {
buffer.put(new byte[length]);
});
}
}
private void updateBuffer() {
final int size = data.size();
if (size <= 0) return;
final int stride = getInstanceFormat().getStride();
final BitSet dirtySet = getDirtyBitSet();
if (dirtySet.isEmpty()) return;
final int firstDirty = dirtySet.nextSetBit(0);
final int lastDirty = dirtySet.previousSetBit(size);
final int offset = firstDirty * stride;
final int length = (1 + lastDirty - firstDirty) * stride;
if (length > 0) {
instanceVBO.map(offset, length, buffer -> {
dirtySet.stream().forEach(i -> {
final D d = data.get(i);
buffer.position(i * stride - offset);
d.write(buffer);
});
});
}
}
private BitSet getDirtyBitSet() {
final int size = data.size();
final BitSet dirtySet = new BitSet(size);
for (int i = 0; i < size; i++) {
D element = data.get(i);
if (element.dirty) {
dirtySet.set(i);
element.dirty = false;
}
}
return dirtySet;
}
private boolean realloc() {
int size = this.data.size();
int stride = getInstanceFormat().getStride();
int requiredSize = size * stride;
if (requiredSize > glBufferSize) {
glBufferSize = requiredSize + stride * 16;
GL15.glBufferData(instanceVBO.getBufferType(), glBufferSize, GL15.GL_STATIC_DRAW);
instanceVBO.map(glBufferSize, buffer -> {
for (D datum : data) {
datum.write(buffer);
}
});
glInstanceCount = size;
return true;
}
return false;
}
private void removeDeletedInstances() {
// figure out which elements are to be removed
// any exception thrown from the filter predicate at this stage
// will leave the collection unmodified
final int oldSize = this.data.size();
int removeCount = 0;
final int size = this.keys.size();
final BitSet removeSet = new BitSet(size);
for (int i=0; i < size; i++) {
final InstanceKey<D> element = this.keys.get(i);
if (!element.isValid()) {
final BitSet removeSet = new BitSet(oldSize);
for (int i = 0; i < oldSize; i++) {
final D element = this.data.get(i);
if (element.removed) {
removeSet.set(i);
removeCount++;
}
}
final int newSize = oldSize - removeCount;
// shift surviving elements left over the spaces left by removed elements
final boolean anyToRemove = removeCount > 0;
if (anyToRemove) {
final int newSize = size - removeCount;
for (int i = 0, j = 0; (i < size) && (j < newSize); i++, j++) {
i = removeSet.nextClearBit(i);
keys.set(j, keys.get(i));
data.set(j, data.get(i));
for (int i = 0, j = 0; (i < oldSize) && (j < newSize); i++, j++) {
i = removeSet.nextClearBit(i);
if (i != j) {
D element = data.get(i);
data.set(j, element);
element.dirty = true;
}
keys.subList(newSize, size).clear();
data.subList(newSize, size).clear();
int firstChanged = removeSet.nextSetBit(0);
for (int i = firstChanged; i < newSize; i++) {
keys.get(i).index = i;
}
minIndexChanged = 0;
maxIndexChanged = newSize - 1;
}
this.anyToRemove = false;
anyToUpdate = true;
return anyToRemove;
}
data.subList(newSize, oldSize).clear();
protected void markIndexChanged(int index) {
if (minIndexChanged < 0) {
minIndexChanged = index;
} else if (index < minIndexChanged) {
minIndexChanged = index;
}
if (maxIndexChanged < 0) {
maxIndexChanged = index;
} else if (index > maxIndexChanged) {
maxIndexChanged = index;
}
}
protected final void verifyKey(InstanceKey<D> key) {
if (key.model != this) throw new IllegalStateException("Provided key does not belong to model.");
if (!key.isValid()) throw new IllegalStateException("Provided key has been invalidated.");
if (key.index >= data.size()) throw new IndexOutOfBoundsException("Key points out of bounds. (" + key.index + " > " + (data.size() - 1) + ")");
if (keys.get(key.index) != key) throw new IllegalStateException("Key desync!!");
}
@Override

View file

@ -5,11 +5,12 @@ import java.util.*;
import javax.annotation.Nullable;
import com.simibubi.create.foundation.render.backend.Backend;
import com.simibubi.create.foundation.render.backend.RenderMaterials;
import com.simibubi.create.foundation.render.backend.MaterialType;
import com.simibubi.create.foundation.render.backend.MaterialTypes;
import com.simibubi.create.foundation.render.backend.gl.BasicProgram;
import com.simibubi.create.foundation.render.backend.gl.shader.ShaderCallback;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.render.backend.core.OrientedData;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.*;
@ -107,11 +108,11 @@ public abstract class InstancedTileRenderer<P extends BasicProgram> {
}
public RenderMaterial<P, InstancedModel<ModelData>> getTransformMaterial() {
return getMaterial(RenderMaterials.TRANSFORMED);
return getMaterial(MaterialTypes.TRANSFORMED);
}
public RenderMaterial<P, InstancedModel<OrientedData>> getOrientedMaterial() {
return getMaterial(RenderMaterials.ORIENTED);
return getMaterial(MaterialTypes.ORIENTED);
}
@SuppressWarnings("unchecked")

View file

@ -1,5 +0,0 @@
package com.simibubi.create.foundation.render.backend.instancing;
public class MaterialType<M extends InstancedModel<?>> {
}

View file

@ -1,8 +1,8 @@
package com.simibubi.create.foundation.render.backend.instancing;
import com.simibubi.create.foundation.render.backend.instancing.impl.IFlatLight;
import com.simibubi.create.foundation.render.backend.instancing.impl.ModelData;
import com.simibubi.create.foundation.render.backend.instancing.impl.OrientedData;
import com.simibubi.create.foundation.render.backend.core.IFlatLight;
import com.simibubi.create.foundation.render.backend.core.ModelData;
import com.simibubi.create.foundation.render.backend.core.OrientedData;
import net.minecraft.block.BlockState;
import net.minecraft.tileentity.TileEntity;
@ -103,7 +103,7 @@ public abstract class TileEntityInstance<T extends TileEntity> implements IInsta
relight(world.getLightLevel(LightType.BLOCK, pos), world.getLightLevel(LightType.SKY, pos), models);
}
protected void relight(BlockPos pos, Stream<IFlatLight<?>> models) {
protected <L extends IFlatLight<?>> void relight(BlockPos pos, Stream<L> models) {
relight(world.getLightLevel(LightType.BLOCK, pos), world.getLightLevel(LightType.SKY, pos), models);
}
@ -111,7 +111,7 @@ public abstract class TileEntityInstance<T extends TileEntity> implements IInsta
relight(block, sky, Arrays.stream(models));
}
protected void relight(int block, int sky, Stream<IFlatLight<?>> models) {
protected <L extends IFlatLight<?>> void relight(int block, int sky, Stream<L> models) {
models.forEach(model -> model.setBlockLight(block).setSkyLight(sky));
}

View file

@ -1,11 +1,12 @@
{
"required": true,
"priority": 1100,
"package": "com.simibubi.create.foundation.mixin",
"compatibilityLevel": "JAVA_8",
"refmap": "create.refmap.json",
"mixins": ["StepSoundMixin"],
"client": [
"TileAddMixin",
"TileWorldHookMixin",
"CancelTileEntityRenderMixin",
"FogColorTrackerMixin",
"LightUpdateMixin",