More Instancers

This commit is contained in:
Jozufozu 2022-01-03 13:55:43 -08:00
parent c8ba7b88cc
commit 5f81b31fe4
10 changed files with 251 additions and 35 deletions

View file

@ -11,6 +11,7 @@ import com.simibubi.create.content.contraptions.components.actors.DrillRenderer;
import com.simibubi.create.content.contraptions.components.actors.DrillTileEntity;
import com.simibubi.create.content.contraptions.components.actors.HarvesterRenderer;
import com.simibubi.create.content.contraptions.components.actors.HarvesterTileEntity;
import com.simibubi.create.content.contraptions.components.actors.PSIInstance;
import com.simibubi.create.content.contraptions.components.actors.PortableFluidInterfaceTileEntity;
import com.simibubi.create.content.contraptions.components.actors.PortableItemInterfaceTileEntity;
import com.simibubi.create.content.contraptions.components.actors.PortableStorageInterfaceRenderer;
@ -484,12 +485,14 @@ public class AllTileEntities {
public static final BlockEntityEntry<PortableItemInterfaceTileEntity> PORTABLE_STORAGE_INTERFACE =
Create.registrate()
.tileEntity("portable_storage_interface", PortableItemInterfaceTileEntity::new)
.instance(() -> PSIInstance::new)
.validBlocks(AllBlocks.PORTABLE_STORAGE_INTERFACE)
.renderer(() -> PortableStorageInterfaceRenderer::new)
.register();
public static final BlockEntityEntry<PortableFluidInterfaceTileEntity> PORTABLE_FLUID_INTERFACE = Create.registrate()
.tileEntity("portable_fluid_interface", PortableFluidInterfaceTileEntity::new)
.instance(() -> PSIInstance::new)
.validBlocks(AllBlocks.PORTABLE_FLUID_INTERFACE)
.renderer(() -> PortableStorageInterfaceRenderer::new)
.register();

View file

@ -0,0 +1,78 @@
package com.simibubi.create.content.contraptions.components.actors;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.materials.model.ModelData;
import com.simibubi.create.foundation.utility.AngleHelper;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
public class PIInstance {
private final MaterialManager materialManager;
private final BlockState blockState;
private final BlockPos instancePos;
private final float angleX;
private final float angleY;
private boolean lit;
ModelData middle;
ModelData top;
public PIInstance(MaterialManager materialManager, BlockState blockState, BlockPos instancePos) {
this.materialManager = materialManager;
this.blockState = blockState;
this.instancePos = instancePos;
Direction facing = blockState.getValue(PortableStorageInterfaceBlock.FACING);
angleX = facing == Direction.UP ? 0 : facing == Direction.DOWN ? 180 : 90;
angleY = AngleHelper.horizontalAngle(facing);
}
public void init(boolean lit) {
this.lit = lit;
middle = materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit), blockState)
.createInstance();
top = materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getTopForState(blockState), blockState)
.createInstance();
}
public void beginFrame(float progress) {
middle.loadIdentity()
.translate(instancePos)
.centre()
.rotateY(angleY)
.rotateX(angleX)
.unCentre();
top.loadIdentity()
.translate(instancePos)
.centre()
.rotateY(angleY)
.rotateX(angleX)
.unCentre();
middle.translate(0, progress * 0.5f + 0.375f, 0);
top.translate(0, progress, 0);
}
public void tick(boolean lit) {
if (this.lit != lit) {
this.lit = lit;
materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(PortableStorageInterfaceRenderer.getMiddleForState(blockState, lit), blockState)
.stealInstance(middle);
}
}
public void remove() {
middle.delete();
top.delete();
}
}

View file

@ -0,0 +1,30 @@
package com.simibubi.create.content.contraptions.components.actors;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementContext;
import com.simibubi.create.content.contraptions.components.structureMovement.render.ActorInstance;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
public class PSIActorInstance extends ActorInstance {
private final PIInstance instance;
public PSIActorInstance(MaterialManager materialManager, VirtualRenderWorld world, MovementContext context) {
super(materialManager, world, context);
instance = new PIInstance(materialManager, context.state, context.localPos);
instance.init(false);
instance.middle.setBlockLight(localBlockLight());
instance.top.setBlockLight(localBlockLight());
}
@Override
public void beginFrame() {
PortableStorageInterfaceTileEntity psi = PortableStorageInterfaceRenderer.getTargetPSI(context);
instance.tick(psi != null && psi.isConnected());
instance.beginFrame(psi == null ? 0f : psi.getExtensionDistance(AnimationTickHolder.getPartialTicks()));
}
}

View file

@ -0,0 +1,48 @@
package com.simibubi.create.content.contraptions.components.actors;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.TickableInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstance;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
public class PSIInstance extends BlockEntityInstance<PortableStorageInterfaceTileEntity> implements DynamicInstance, TickableInstance {
private final PIInstance instance;
public PSIInstance(MaterialManager materialManager, PortableStorageInterfaceTileEntity tile) {
super(materialManager, tile);
instance = new PIInstance(materialManager, blockState, getInstancePosition());
}
@Override
public void init() {
instance.init(isLit());
}
@Override
public void tick() {
instance.tick(isLit());
}
@Override
public void beginFrame() {
instance.beginFrame(blockEntity.getExtensionDistance(AnimationTickHolder.getPartialTicks()));
}
@Override
public void updateLight() {
relight(pos, instance.middle, instance.top);
}
@Override
public void remove() {
instance.remove();
}
private boolean isLit() {
return blockEntity.isConnected();
}
}

View file

@ -2,9 +2,14 @@ package com.simibubi.create.content.contraptions.components.actors;
import java.util.Optional;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.virtual.VirtualRenderWorld;
import com.simibubi.create.content.contraptions.components.structureMovement.MovementBehaviour;
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.ContraptionMatrices;
import com.simibubi.create.foundation.utility.VecHelper;
@ -30,11 +35,23 @@ public class PortableStorageInterfaceMovement extends MovementBehaviour {
.getNormal()).scale(1.85f);
}
@Override
public boolean hasSpecialInstancedRendering() {
return true;
}
@Nullable
@Override
public ActorInstance createInstance(MaterialManager materialManager, VirtualRenderWorld simulationWorld, MovementContext context) {
return new PSIActorInstance(materialManager, simulationWorld, context);
}
@Override
@OnlyIn(Dist.CLIENT)
public void renderInContraption(MovementContext context, VirtualRenderWorld renderWorld,
ContraptionMatrices matrices, MultiBufferSource buffer) {
PortableStorageInterfaceRenderer.renderInContraption(context, renderWorld, matrices, buffer);
if (!Backend.isOn())
PortableStorageInterfaceRenderer.renderInContraption(context, renderWorld, matrices, buffer);
}
@Override

View file

@ -86,17 +86,16 @@ public class PortableStorageInterfaceRenderer extends SafeTileEntityRenderer<Por
.unCentre();
}
protected static PortableStorageInterfaceTileEntity getTargetPSI(MovementContext context) {
static PortableStorageInterfaceTileEntity getTargetPSI(MovementContext context) {
String _workingPos_ = PortableStorageInterfaceMovement._workingPos_;
if (!context.contraption.stalled || !context.data.contains(_workingPos_))
return null;
BlockPos pos = NbtUtils.readBlockPos(context.data.getCompound(_workingPos_));
BlockEntity tileEntity = context.world.getBlockEntity(pos);
if (!(tileEntity instanceof PortableStorageInterfaceTileEntity))
if (!(tileEntity instanceof PortableStorageInterfaceTileEntity psi))
return null;
PortableStorageInterfaceTileEntity psi = (PortableStorageInterfaceTileEntity) tileEntity;
if (!psi.isTransferring())
return null;
return psi;

View file

@ -34,7 +34,6 @@ public class DeployerInstance extends ShaftInstance implements DynamicInstance,
PartialModel currentHand;
float progress;
private boolean newHand = false;
public DeployerInstance(MaterialManager dispatcher, KineticTileEntity tile) {
super(dispatcher, tile);
@ -50,28 +49,34 @@ public class DeployerInstance extends ShaftInstance implements DynamicInstance,
pole = getOrientedMaterial().getModel(AllBlockPartials.DEPLOYER_POLE, blockState).createInstance();
updateHandPose();
relight(pos, pole);
currentHand = this.tile.getHandPose();
progress = getProgress(AnimationTickHolder.getPartialTicks());
hand = getOrientedMaterial().getModel(currentHand, blockState).createInstance();
progress = getProgress(AnimationTickHolder.getPartialTicks());
updateRotation(pole, hand, yRot, xRot, zRot);
updatePosition();
}
@Override
public void tick() {
newHand = updateHandPose();
}
PartialModel handPose = tile.getHandPose();
if (currentHand != handPose) {
currentHand = handPose;
getOrientedMaterial().getModel(currentHand, blockState)
.stealInstance(hand);
}
}
@Override
public void beginFrame() {
float newProgress = getProgress(AnimationTickHolder.getPartialTicks());
if (!newHand && Mth.equal(newProgress, progress)) return;
if (Mth.equal(newProgress, progress)) return;
progress = newProgress;
newHand = false;
updatePosition();
}
@ -89,24 +94,7 @@ public class DeployerInstance extends ShaftInstance implements DynamicInstance,
pole.delete();
}
private boolean updateHandPose() {
PartialModel handPose = tile.getHandPose();
if (currentHand == handPose) return false;
currentHand = handPose;
if (hand != null) hand.delete();
hand = getOrientedMaterial().getModel(currentHand, blockState).createInstance();
relight(pos, hand);
updateRotation(pole, hand, yRot, xRot, zRot);
updatePosition();
return true;
}
private float getProgress(float partialTicks) {
private float getProgress(float partialTicks) {
if (tile.state == DeployerTileEntity.State.EXPANDING)
return 1 - (tile.timer - partialTicks * tile.getTimerSpeed()) / 1000f;
if (tile.state == DeployerTileEntity.State.RETRACTING)

View file

@ -2,25 +2,76 @@ package com.simibubi.create.content.contraptions.fluids;
import com.jozufozu.flywheel.api.Instancer;
import com.jozufozu.flywheel.api.MaterialManager;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.core.Materials;
import com.jozufozu.flywheel.core.materials.model.ModelData;
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.content.contraptions.base.flwdata.RotatingData;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
public class PumpCogInstance extends SingleRotatingInstance {
public class PumpCogInstance extends SingleRotatingInstance implements DynamicInstance {
public PumpCogInstance(MaterialManager modelManager, KineticTileEntity tile) {
private final PumpTileEntity blockEntity = (PumpTileEntity) super.blockEntity;
private final ModelData[] arrows = new ModelData[2];
private final Direction direction = blockState.getValue(PumpBlock.FACING);
public PumpCogInstance(MaterialManager modelManager, PumpTileEntity tile) {
super(modelManager, tile);
}
@Override
@Override
public void init() {
super.init();
materialManager.defaultSolid()
.material(Materials.TRANSFORMED)
.getModel(AllBlockPartials.MECHANICAL_PUMP_ARROW, blockState)
.createInstances(arrows);
}
@Override
public void beginFrame() {
float angle = Mth.lerp(blockEntity.arrowDirection.getValue(AnimationTickHolder.getPartialTicks()), 0, 90) - 90;
for (int i = 0, arrowsLength = arrows.length; i < arrowsLength; i++) {
arrows[i].loadIdentity()
.translate(getInstancePosition())
.centre()
.rotateY(AngleHelper.horizontalAngle(direction) + 180)
.rotateX(-AngleHelper.verticalAngle(direction) - 90)
.unCentre()
.translate(.5, 14 / 16f, .5)
.rotateY(90 * i)
.rotateZ(angle)
.translateBack(.5, 14 / 16f, .5);
}
}
@Override
public void updateLight() {
super.updateLight();
relight(pos, arrows);
}
@Override
protected Instancer<RotatingData> getModel() {
BlockState referenceState = blockEntity.getBlockState();
Direction facing = referenceState.getValue(BlockStateProperties.FACING);
return getRotatingMaterial().getModel(AllBlockPartials.MECHANICAL_PUMP_COG, referenceState, facing);
}
@Override
public void remove() {
super.remove();
for (ModelData arrow : arrows) {
arrow.delete();
}
}
}

View file

@ -1,5 +1,6 @@
package com.simibubi.create.content.contraptions.fluids;
import com.jozufozu.flywheel.backend.Backend;
import com.mojang.blaze3d.vertex.PoseStack;
import com.simibubi.create.AllBlockPartials;
import com.simibubi.create.content.contraptions.base.KineticTileEntity;
@ -26,6 +27,7 @@ public class PumpRenderer extends KineticTileEntityRenderer {
protected void renderSafe(KineticTileEntity te, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay) {
super.renderSafe(te, partialTicks, ms, buffer, light, overlay);
if (Backend.canUseInstancing(te.getLevel())) return;
if (!(te instanceof PumpTileEntity pump))
return;
Vec3 rotationOffset = new Vec3(.5, 14 / 16f, .5);

View file

@ -74,7 +74,7 @@ public class PumpTileEntity extends KineticTileEntity {
if (!isVirtual())
return;
}
// if (pressureUpdate)
// updatePressureChange();