From 5abc1e0fe73a89e4671c395cfa1b6826edbefae0 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Fri, 2 Apr 2021 13:38:28 -0700 Subject: [PATCH] Instanced pulleys first pass --- .../com/simibubi/create/AllBlockPartials.java | 39 +--- .../com/simibubi/create/AllTileEntities.java | 3 +- .../contraptions/base/HalfShaftInstance.java | 2 +- .../base/ShaftlessCogInstance.java | 4 +- .../components/actors/DrillInstance.java | 10 +- .../components/crank/HandCrankInstance.java | 3 +- .../components/fan/FanInstance.java | 9 +- .../components/flywheel/FlyWheelInstance.java | 13 +- .../millstone/MillStoneCogInstance.java | 3 +- .../components/saw/SawInstance.java | 12 +- .../pulley/AbstractPulleyRenderer.java | 4 + .../pulley/PulleyInstance.java | 209 ++++++++++++++++++ .../pulley/PulleyRenderer.java | 24 +- .../pulley/PulleyTileEntity.java | 2 +- .../contraptions/fluids/PumpCogInstance.java | 8 +- .../relays/belt/BeltInstance.java | 3 +- .../relays/encased/SplitShaftInstance.java | 6 +- .../relays/gearbox/GearboxInstance.java | 6 +- .../block/mechanicalArm/ArmInstance.java | 2 +- .../create/foundation/OptionalUtil.java | 24 ++ .../backend/instancing/RenderMaterial.java | 8 +- .../instancing/util/ConditionalInstance.java | 52 +++++ .../instancing/util/InstanceGroup.java | 83 +++++++ .../instancing/util/SelectInstance.java | 59 +++++ 24 files changed, 512 insertions(+), 76 deletions(-) create mode 100644 src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyInstance.java create mode 100644 src/main/java/com/simibubi/create/foundation/OptionalUtil.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/ConditionalInstance.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/InstanceGroup.java create mode 100644 src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/SelectInstance.java diff --git a/src/main/java/com/simibubi/create/AllBlockPartials.java b/src/main/java/com/simibubi/create/AllBlockPartials.java index 95ff6745c..dc24ad0d0 100644 --- a/src/main/java/com/simibubi/create/AllBlockPartials.java +++ b/src/main/java/com/simibubi/create/AllBlockPartials.java @@ -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.MaterialTypes; +import com.simibubi.create.foundation.render.backend.MaterialType; 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.core.ModelData; +import com.simibubi.create.foundation.render.backend.instancing.RenderMaterial; import com.simibubi.create.foundation.utility.AngleHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.Lang; @@ -237,20 +237,7 @@ public class AllBlockPartials { return CreateClient.bufferCache.renderDirectionalPartial(this, referenceState, facing, ms); } - public InstancedModel renderOnRotating(InstancedTileRenderer ctx, BlockState referenceState) { - return ctx.getMaterial(KineticRenderMaterials.ROTATING).getModel(this, referenceState); - } - - public InstancedModel renderOnBelt(InstancedTileRenderer ctx, BlockState referenceState) { - return ctx.getMaterial(KineticRenderMaterials.BELTS).getModel(this, referenceState); - } - - public InstancedModel renderOnDirectionalSouthRotating(InstancedTileRenderer dispatcher, BlockState referenceState) { - Direction facing = referenceState.get(FACING); - return renderOnDirectionalSouthRotating(dispatcher, referenceState, facing); - } - - public InstancedModel renderOnDirectionalSouthRotating(InstancedTileRenderer dispatcher, BlockState referenceState, Direction facing) { + public > M getModel(RenderMaterial mat, BlockState referenceState, Direction facing) { Supplier ms = () -> { MatrixStack stack = new MatrixStack(); MatrixStacker.of(stack) @@ -260,25 +247,7 @@ public class AllBlockPartials { .unCentre(); return stack; }; - return dispatcher.getMaterial(KineticRenderMaterials.ROTATING).getModel(this, referenceState, facing, ms); - } - - public InstancedModel renderOnHorizontalModel(InstancedTileRenderer dispatcher, BlockState referenceState) { - Direction facing = referenceState.get(HORIZONTAL_FACING); - return renderOnDirectionalSouthModel(dispatcher, referenceState, facing); - } - - public InstancedModel renderOnDirectionalSouthModel(InstancedTileRenderer dispatcher, BlockState referenceState, Direction facing) { - Supplier ms = () -> { - MatrixStack stack = new MatrixStack(); - MatrixStacker.of(stack) - .centre() - .rotateY(AngleHelper.horizontalAngle(facing)) - .rotateX(AngleHelper.verticalAngle(facing)) - .unCentre(); - return stack; - }; - return dispatcher.getMaterial(MaterialTypes.TRANSFORMED).getModel(this, referenceState, facing, ms); + return mat.getModel(this, referenceState, facing, ms); } } diff --git a/src/main/java/com/simibubi/create/AllTileEntities.java b/src/main/java/com/simibubi/create/AllTileEntities.java index 219269b08..8f2ecaa00 100644 --- a/src/main/java/com/simibubi/create/AllTileEntities.java +++ b/src/main/java/com/simibubi/create/AllTileEntities.java @@ -61,6 +61,7 @@ import com.simibubi.create.content.contraptions.components.structureMovement.gan import com.simibubi.create.content.contraptions.components.structureMovement.mounted.CartAssemblerTileEntity; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.piston.MechanicalPistonTileEntity; +import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyInstance; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyRenderer; import com.simibubi.create.content.contraptions.components.structureMovement.pulley.PulleyTileEntity; import com.simibubi.create.content.contraptions.components.turntable.TurntableTileEntity; @@ -398,7 +399,7 @@ public class AllTileEntities { public static final TileEntityEntry ROPE_PULLEY = Create.registrate() .tileEntity("rope_pulley", PulleyTileEntity::new) - .instance(() -> ShaftInstance::new) + .instance(() -> PulleyInstance::new) .validBlocks(AllBlocks.ROPE_PULLEY) .renderer(() -> PulleyRenderer::new) .register(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java index 8e974deab..4b834f520 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/HalfShaftInstance.java @@ -15,7 +15,7 @@ public class HalfShaftInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { Direction dir = getShaftDirection(); - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(renderer, blockState, dir); + return AllBlockPartials.SHAFT_HALF.getModel(getRotatingMaterial(), blockState, dir); } protected Direction getShaftDirection() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java index 7c9fd17c2..16f85ab32 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/ShaftlessCogInstance.java @@ -12,6 +12,6 @@ public class ShaftlessCogInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - return AllBlockPartials.SHAFTLESS_COGWHEEL.renderOnRotating(renderer, tile.getBlockState()); - } + return renderer.getMaterial(KineticRenderMaterials.ROTATING).getModel(AllBlockPartials.SHAFTLESS_COGWHEEL, tile.getBlockState()); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java index da5a33476..04508390b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/actors/DrillInstance.java @@ -1,11 +1,16 @@ package com.simibubi.create.content.contraptions.components.actors; +import net.minecraft.block.BlockState; + import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; 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 static net.minecraft.state.properties.BlockStateProperties.FACING; + public class DrillInstance extends SingleRotatingInstance { public DrillInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { @@ -14,6 +19,7 @@ public class DrillInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - return AllBlockPartials.DRILL_HEAD.renderOnDirectionalSouthRotating(renderer, tile.getBlockState()); - } + BlockState referenceState = tile.getBlockState(); + return AllBlockPartials.DRILL_HEAD.getModel(getRotatingMaterial(), referenceState, referenceState.get(FACING)); + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java index 33fb21234..9ca46e198 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crank/HandCrankInstance.java @@ -3,6 +3,7 @@ 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.SingleRotatingInstance; +import com.simibubi.create.foundation.render.backend.MaterialTypes; import com.simibubi.create.foundation.render.backend.instancing.*; import com.simibubi.create.foundation.render.backend.core.ModelData; import com.simibubi.create.foundation.utility.AnimationTickHolder; @@ -29,7 +30,7 @@ public class HandCrankInstance extends SingleRotatingInstance implements IDynami return; facing = blockState.get(BlockStateProperties.FACING); - InstancedModel model = renderedHandle.renderOnDirectionalSouthModel(modelManager, blockState, facing.getOpposite()); + InstancedModel model = renderedHandle.getModel(getTransformMaterial(), blockState, facing.getOpposite()); crank = model.createInstance(); rotateCrank(); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java index 62ab42d6e..f2165b8d2 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/fan/FanInstance.java @@ -3,6 +3,7 @@ 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.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; @@ -16,14 +17,16 @@ public class FanInstance extends KineticTileInstance { protected final RotatingData shaft; protected final RotatingData fan; final Direction direction; + private final Direction opposite; public FanInstance(InstancedTileRenderer modelManager, EncasedFanTileEntity tile) { super(modelManager, tile); direction = blockState.get(FACING); - shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); - fan = AllBlockPartials.ENCASED_FAN_INNER.renderOnDirectionalSouthRotating(modelManager, blockState, direction.getOpposite()).createInstance(); + opposite = direction.getOpposite(); + shaft = AllBlockPartials.SHAFT_HALF.getModel(getRotatingMaterial(), blockState, opposite).createInstance(); + fan = AllBlockPartials.ENCASED_FAN_INNER.getModel(getRotatingMaterial(), blockState, opposite).createInstance(); setup(shaft); setup(fan, getFanSpeed()); @@ -46,7 +49,7 @@ public class FanInstance extends KineticTileInstance { @Override public void updateLight() { - BlockPos behind = pos.offset(direction.getOpposite()); + BlockPos behind = pos.offset(opposite); relight(behind, shaft); BlockPos inFront = pos.offset(direction); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java index c2975d56c..542fda0a9 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/flywheel/FlyWheelInstance.java @@ -6,19 +6,25 @@ import java.util.List; import com.google.common.collect.Lists; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; +import com.simibubi.create.foundation.render.backend.MaterialTypes; import com.simibubi.create.foundation.render.backend.instancing.*; 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; + +import net.minecraft.block.BlockState; import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.util.Direction; import net.minecraft.util.Rotation; import net.minecraft.util.math.MathHelper; +import static net.minecraft.state.properties.BlockStateProperties.HORIZONTAL_FACING; + public class FlyWheelInstance extends KineticTileInstance implements IDynamicInstance { protected final Direction facing; @@ -42,11 +48,12 @@ public class FlyWheelInstance extends KineticTileInstance im public FlyWheelInstance(InstancedTileRenderer modelManager, FlywheelTileEntity tile) { super(modelManager, tile); - facing = blockState.get(BlockStateProperties.HORIZONTAL_FACING); + facing = blockState.get(HORIZONTAL_FACING); shaft = setup(shaftModel().createInstance()); - wheel = AllBlockPartials.FLYWHEEL.renderOnHorizontalModel(modelManager, blockState.rotate(Rotation.CLOCKWISE_90)).createInstance(); + BlockState referenceState = blockState.rotate(Rotation.CLOCKWISE_90); + wheel = AllBlockPartials.FLYWHEEL.getModel(getTransformMaterial(), referenceState, referenceState.get(HORIZONTAL_FACING)).createInstance(); connection = FlywheelBlock.getConnection(blockState); if (connection != null) { @@ -152,7 +159,7 @@ public class FlyWheelInstance extends KineticTileInstance im } protected InstancedModel shaftModel() { - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(renderer, blockState, facing.getOpposite()); + return AllBlockPartials.SHAFT_HALF.getModel(getRotatingMaterial(), blockState, facing.getOpposite()); } protected void transformConnector(MatrixStacker ms, boolean upper, boolean rotating, float angle, boolean flip) { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java index dded6ee67..9e5f5c390 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/millstone/MillStoneCogInstance.java @@ -1,6 +1,7 @@ package com.simibubi.create.content.contraptions.components.millstone; import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; @@ -15,6 +16,6 @@ public class MillStoneCogInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - return AllBlockPartials.MILLSTONE_COG.renderOnRotating(renderer, tile.getBlockState()); + return getRotatingMaterial().getModel(AllBlockPartials.MILLSTONE_COG, tile.getBlockState()); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java index 606ffe62b..3c877353f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/saw/SawInstance.java @@ -3,12 +3,14 @@ package com.simibubi.create.content.contraptions.components.saw; import static net.minecraft.state.properties.BlockStateProperties.FACING; import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import net.minecraft.block.BlockState; import net.minecraft.util.Rotation; public class SawInstance extends SingleRotatingInstance { @@ -19,9 +21,11 @@ public class SawInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - if (blockState.get(FACING).getAxis().isHorizontal()) - return AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(renderer, blockState.rotate(tile.getWorld(), tile.getPos(), Rotation.CLOCKWISE_180)); - else - return getRotatingMaterial().getModel(shaft()); + if (blockState.get(FACING).getAxis().isHorizontal()) { + BlockState referenceState = blockState.rotate(tile.getWorld(), tile.getPos(), Rotation.CLOCKWISE_180); + return AllBlockPartials.SHAFT_HALF.getModel(getRotatingMaterial(), referenceState, referenceState.get(FACING)); + } else { + return getRotatingMaterial().getModel(shaft()); + } } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/AbstractPulleyRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/AbstractPulleyRenderer.java index 17d3ca9ce..f707114df 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/AbstractPulleyRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/AbstractPulleyRenderer.java @@ -7,6 +7,7 @@ import com.simibubi.create.content.contraptions.base.IRotate; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.foundation.render.SuperByteBuffer; +import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; import com.simibubi.create.foundation.utility.AngleHelper; import net.minecraft.block.BlockState; @@ -41,6 +42,9 @@ public abstract class AbstractPulleyRenderer extends KineticTileEntityRenderer { @Override protected void renderSafe(KineticTileEntity te, float partialTicks, MatrixStack ms, IRenderTypeBuffer buffer, int light, int overlay) { + + if (FastRenderDispatcher.available(te.getWorld())) return; + super.renderSafe(te, partialTicks, ms, buffer, light, overlay); float offset = getOffset(te, partialTicks); boolean running = isRunning(te); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyInstance.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyInstance.java new file mode 100644 index 000000000..e32888ee5 --- /dev/null +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyInstance.java @@ -0,0 +1,209 @@ +package com.simibubi.create.content.contraptions.components.structureMovement.pulley; + +import net.minecraft.client.renderer.Vector3f; +import net.minecraft.util.Direction; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.MathHelper; +import net.minecraft.world.ILightReader; +import net.minecraft.world.LightType; + +import java.util.Arrays; +import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.relays.encased.ShaftInstance; +import com.simibubi.create.foundation.render.backend.core.OrientedData; +import com.simibubi.create.foundation.render.backend.instancing.*; +import com.simibubi.create.foundation.render.backend.instancing.util.ConditionalInstance; +import com.simibubi.create.foundation.render.backend.instancing.util.InstanceGroup; +import com.simibubi.create.foundation.render.backend.instancing.util.SelectInstance; +import com.simibubi.create.foundation.render.backend.light.GridAlignedBB; +import com.simibubi.create.foundation.render.backend.light.LightUpdateListener; +import com.simibubi.create.foundation.render.backend.light.LightUpdater; +import com.simibubi.create.foundation.utility.AnimationTickHolder; + +public class PulleyInstance extends ShaftInstance implements IDynamicInstance, LightUpdateListener { + + final PulleyTileEntity tile = (PulleyTileEntity) super.tile; + final OrientedData coil; + final SelectInstance magnet; + final InstanceGroup rope; + final ConditionalInstance halfRope; + + private float offset; + private final Direction rotatingAbout; + private final Vector3f rotationAxis; + + private byte[] bLight = new byte[1]; + private byte[] sLight = new byte[1]; + private GridAlignedBB volume; + + public PulleyInstance(InstancedTileRenderer dispatcher, PulleyTileEntity tile) { + super(dispatcher, tile); + + rotatingAbout = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis); + rotationAxis = rotatingAbout.getUnitVector(); + updateOffset(); + + coil = getCoilModel() + .createInstance() + .setPosition(getInstancePosition()); + + magnet = new SelectInstance<>(this::getMagnetModelIndex); + magnet.addModel(getMagnetModel()) + .addModel(getHalfMagnetModel()); + + rope = new InstanceGroup<>(getRopeModel()); + resizeRope(); + + halfRope = new ConditionalInstance<>(getHalfRopeModel(), this::shouldRenderHalfRope); + + beginFrame(); + } + + @Override + public void beginFrame() { + updateOffset(); + + coil.setRotation(rotationAxis.getDegreesQuaternion(offset * 180)); + magnet.update().get().ifPresent(data -> + data.setPosition(getInstancePosition()) + .nudge(0, -offset, 0) + .setBlockLight(bLight[bLight.length - 1]) + .setSkyLight(sLight[sLight.length - 1]) + ); + + halfRope.check().get().ifPresent(rope -> { + float f = offset % 1; + float halfRopeNudge = f > .75f ? f - 1 : f; + + rope.setPosition(getInstancePosition()) + .nudge(0, -halfRopeNudge, 0) + .setBlockLight(bLight[0]) + .setSkyLight(sLight[0]); + }); + + if (isRunning()) { + resizeRope(); + int size = rope.size(); + for (int i = 0; i < size; i++) { + rope.get(i) + .setPosition(getInstancePosition()) + .nudge(0, -offset + i + 1, 0) + .setBlockLight(bLight[size - i]) + .setSkyLight(sLight[size - i]); + } + } else { + rope.clear(); + } + } + + @Override + public void updateLight() { + super.updateLight(); + relight(pos, coil); + } + + @Override + public void remove() { + super.remove(); + coil.delete(); + magnet.delete(); + rope.clear(); + halfRope.delete(); + } + + protected InstancedModel getRopeModel() { + return getOrientedMaterial().getModel(AllBlocks.ROPE.getDefaultState()); + } + + protected InstancedModel getMagnetModel() { + return getOrientedMaterial().getModel(AllBlocks.PULLEY_MAGNET.getDefaultState()); + } + + protected InstancedModel getHalfMagnetModel() { + return getOrientedMaterial().getModel(AllBlockPartials.ROPE_HALF_MAGNET, blockState); + } + + protected InstancedModel getCoilModel() { + return AllBlockPartials.ROPE_COIL.getModel(getOrientedMaterial(), blockState, rotatingAbout); + } + + protected InstancedModel getHalfRopeModel() { + return getOrientedMaterial().getModel(AllBlockPartials.ROPE_HALF, blockState); + } + + protected float getOffset() { + float partialTicks = AnimationTickHolder.getPartialTicks(); + return PulleyRenderer.getTileOffset(partialTicks, tile); + } + + protected boolean isRunning() { + return tile.running || tile.isVirtual(); + } + + protected void resizeRope() { + if (rope.resize(getNeededRopeCount())) { + + int length = MathHelper.ceil(offset); + volume = GridAlignedBB.from(pos.down(length), pos); + volume.fixMinMax(); + + bLight = Arrays.copyOf(bLight, length + 1); + sLight = Arrays.copyOf(sLight, length + 1); + + initLight(world, volume); + + LightUpdater.getInstance().startListening(volume, this); + } + } + + private void updateOffset() { + offset = getOffset(); + } + + private int getNeededRopeCount() { + return Math.max(0, MathHelper.ceil(offset - 1.25f)); + } + + private boolean shouldRenderHalfRope() { + float f = offset % 1; + return offset > .75f && (f < .25f || f > .75f); + } + + private int getMagnetModelIndex() { + if (isRunning() || offset == 0) { + return offset > .25f ? 0 : 1; + } else { + return -1; + } + } + + @Override + public boolean decreaseFramerateWithDistance() { + return false; + } + + @Override + public boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) { + changed.intersectAssign(volume); + + initLight(world, changed); + + return false; + } + + private void initLight(ILightReader world, GridAlignedBB changed) { + int top = this.pos.getY(); + BlockPos.Mutable pos = new BlockPos.Mutable(); + changed.forEachContained((x, y, z) -> { + pos.setPos(x, y, z); + byte block = (byte) world.getLightLevel(LightType.BLOCK, pos); + byte sky = (byte) world.getLightLevel(LightType.SKY, pos); + + int i = top - y; + + bLight[i] = block; + sLight[i] = sky; + }); + } +} diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java index 00d708294..740302722 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyRenderer.java @@ -41,16 +41,7 @@ public class PulleyRenderer extends AbstractPulleyRenderer { @Override protected float getOffset(KineticTileEntity te, float partialTicks) { PulleyTileEntity pulley = (PulleyTileEntity) te; - float offset = pulley.getInterpolatedOffset(partialTicks); - - if (pulley.movedContraption != null) { - AbstractContraptionEntity e = pulley.movedContraption; - PulleyContraption c = (PulleyContraption) pulley.movedContraption.getContraption(); - double entityPos = MathHelper.lerp(partialTicks, e.lastTickPosY, e.getY()); - offset = (float) -(entityPos - c.anchor.getY() - c.initialOffset); - } - - return offset; + return getTileOffset(partialTicks, pulley); } @Override @@ -58,4 +49,17 @@ public class PulleyRenderer extends AbstractPulleyRenderer { return ((PulleyTileEntity) te).running || te.isVirtual(); } + + static float getTileOffset(float partialTicks, PulleyTileEntity tile) { + float offset = tile.getInterpolatedOffset(partialTicks); + + if (tile.movedContraption != null) { + AbstractContraptionEntity e = tile.movedContraption; + PulleyContraption c = (PulleyContraption) tile.movedContraption.getContraption(); + double entityPos = MathHelper.lerp(partialTicks, e.lastTickPosY, e.getY()); + offset = (float) -(entityPos - c.anchor.getY() - c.initialOffset); + } + + return offset; + } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java index a185e14cc..8b1d8afab 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyTileEntity.java @@ -241,6 +241,6 @@ public class PulleyTileEntity extends LinearActuatorTileEntity { @Override public boolean shouldRenderAsTE() { - return true; + return false; } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java index 786c5dca8..27ffe2b5c 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/fluids/PumpCogInstance.java @@ -1,12 +1,17 @@ package com.simibubi.create.content.contraptions.fluids; +import net.minecraft.block.BlockState; + import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.content.contraptions.base.SingleRotatingInstance; import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; import com.simibubi.create.foundation.render.backend.instancing.InstancedTileRenderer; +import static net.minecraft.state.properties.BlockStateProperties.FACING; + public class PumpCogInstance extends SingleRotatingInstance { public PumpCogInstance(InstancedTileRenderer modelManager, KineticTileEntity tile) { @@ -15,6 +20,7 @@ public class PumpCogInstance extends SingleRotatingInstance { @Override protected InstancedModel getModel() { - return AllBlockPartials.MECHANICAL_PUMP_COG.renderOnDirectionalSouthRotating(renderer, tile.getBlockState()); + BlockState referenceState = tile.getBlockState(); + return AllBlockPartials.MECHANICAL_PUMP_COG.getModel(getRotatingMaterial(), referenceState, referenceState.get(FACING)); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java index 9983b0899..18eb22b0b 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltInstance.java @@ -6,6 +6,7 @@ import java.util.function.Supplier; import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllBlocks; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; @@ -59,7 +60,7 @@ public class BeltInstance extends KineticTileInstance { AllBlockPartials beltPartial = BeltRenderer.getBeltPartial(diagonal, start, end, bottom); SpriteShiftEntry spriteShift = BeltRenderer.getSpriteShiftEntry(color, diagonal, bottom); - InstancedModel beltModel = beltPartial.renderOnBelt(modelManager, blockState); + InstancedModel beltModel = modelManager.getMaterial(KineticRenderMaterials.BELTS).getModel(beltPartial, blockState); keys.add(setup(beltModel.createInstance(), bottom, spriteShift)); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java index 9a4e50292..c4deb4a5f 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/encased/SplitShaftInstance.java @@ -4,11 +4,13 @@ import java.util.ArrayList; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.IRotate; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; 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.render.backend.instancing.RenderMaterial; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.block.Block; @@ -25,9 +27,11 @@ public class SplitShaftInstance extends KineticTileInstance> rotatingMaterial = getRotatingMaterial(); + for (Direction dir : Iterate.directionsInAxis(getRotationAxis())) { - InstancedModel half = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, dir); + InstancedModel half = AllBlockPartials.SHAFT_HALF.getModel(rotatingMaterial, blockState, dir); float splitSpeed = speed * tile.getRotationSpeedModifier(dir); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java index bfece3f61..8c9469c00 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/gearbox/GearboxInstance.java @@ -4,11 +4,13 @@ import java.util.EnumMap; import java.util.Map; import com.simibubi.create.AllBlockPartials; +import com.simibubi.create.content.contraptions.base.KineticRenderMaterials; import com.simibubi.create.content.contraptions.base.KineticTileInstance; import com.simibubi.create.content.contraptions.base.RotatingData; 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.render.backend.instancing.RenderMaterial; import com.simibubi.create.foundation.utility.Iterate; import net.minecraft.state.properties.BlockStateProperties; @@ -32,12 +34,14 @@ public class GearboxInstance extends KineticTileInstance { int skyLight = world.getLightLevel(LightType.SKY, pos); updateSourceFacing(); + RenderMaterial> rotatingMaterial = getRotatingMaterial(); + for (Direction direction : Iterate.directions) { final Direction.Axis axis = direction.getAxis(); if (boxAxis == axis) continue; - InstancedModel shaft = AllBlockPartials.SHAFT_HALF.renderOnDirectionalSouthRotating(modelManager, blockState, direction); + InstancedModel shaft = AllBlockPartials.SHAFT_HALF.getModel(rotatingMaterial, blockState, direction); RotatingData key = shaft.createInstance(); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java index eaf1afca3..ce716f4e8 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmInstance.java @@ -170,7 +170,7 @@ public class ArmInstance extends SingleRotatingInstance implements IDynamicInsta @Override protected InstancedModel getModel() { - return AllBlockPartials.ARM_COG.renderOnRotating(renderer, tile.getBlockState()); + return getRotatingMaterial().getModel(AllBlockPartials.ARM_COG, tile.getBlockState()); } @Override diff --git a/src/main/java/com/simibubi/create/foundation/OptionalUtil.java b/src/main/java/com/simibubi/create/foundation/OptionalUtil.java new file mode 100644 index 000000000..f15ec5969 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/OptionalUtil.java @@ -0,0 +1,24 @@ +package com.simibubi.create.foundation; + +import java.util.Optional; +import java.util.function.Supplier; + +public class OptionalUtil { + + public static Optional thenTry(Optional first, Optional thenTry) { + if (first.isPresent()) { + return first; + } else { + return thenTry; + } + } + + public static Optional thenTryLazy(Supplier> first, Supplier> thenTry) { + Optional one = first.get(); + if (one.isPresent()) { + return one; + } else { + return thenTry.get(); + } + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java index d9557abec..7815a764f 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/RenderMaterial.java @@ -85,13 +85,7 @@ public class RenderMaterial

cache : models.values()) { - for (MODEL model : cache.asMap().values()) { - if (!model.isEmpty()) { - model.render(); - } - } - } + runOnAll(InstancedModel::render); } public void runOnAll(Consumer f) { diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/ConditionalInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/ConditionalInstance.java new file mode 100644 index 000000000..94b891039 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/ConditionalInstance.java @@ -0,0 +1,52 @@ +package com.simibubi.create.foundation.render.backend.instancing.util; + +import java.util.Optional; +import javax.annotation.Nullable; +import com.simibubi.create.foundation.render.backend.instancing.InstanceData; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; + +public class ConditionalInstance { + + final InstancedModel model; + Condition condition; + + @Nullable + private D instance; + + public ConditionalInstance(InstancedModel model, Condition condition) { + this.model = model; + this.condition = condition; + + check(); + } + + public ConditionalInstance setCondition(Condition condition) { + this.condition = condition; + return this; + } + + public ConditionalInstance check() { + boolean shouldShow = condition.shouldShow(); + if (shouldShow && instance == null) { + instance = model.createInstance(); + } else if (!shouldShow && instance != null) { + instance.delete(); + instance = null; + } + + return this; + } + + public Optional get() { + return Optional.ofNullable(instance); + } + + public void delete() { + if (instance != null) instance.delete(); + } + + @FunctionalInterface + public interface Condition { + boolean shouldShow(); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/InstanceGroup.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/InstanceGroup.java new file mode 100644 index 000000000..15c5871fe --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/InstanceGroup.java @@ -0,0 +1,83 @@ +package com.simibubi.create.foundation.render.backend.instancing.util; + +import net.minecraft.util.NonNullList; + +import java.util.*; +import com.simibubi.create.foundation.render.backend.instancing.InstanceData; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; + +public class InstanceGroup extends AbstractCollection { + + final InstancedModel model; + final List backing; + + public InstanceGroup(InstancedModel model) { + this.model = model; + + this.backing = new ArrayList<>(); + } + + public InstanceGroup(InstancedModel model, int size) { + this.model = model; + + this.backing = new ArrayList<>(size); + + for (int i = 0; i < size; i++) { + addInstance(); + } + } + + /** + * + * @param count + * @return True if the number of elements changed. + */ + public boolean resize(int count) { + int size = size(); + if (count == size) return false; + + if (count <= 0) { + clear(); + return size > 0; + } + + if (count > size) { + for (int i = size; i < count; i++) { + addInstance(); + } + } else { + List unnecessary = backing.subList(count, size); + unnecessary.forEach(InstanceData::delete); + unnecessary.clear(); + } + + return true; + } + + public InstanceData addInstance() { + D instance = model.createInstance(); + backing.add(instance); + + return instance; + } + + public D get(int index) { + return backing.get(index); + } + + @Override + public Iterator iterator() { + return backing.iterator(); + } + + @Override + public int size() { + return backing.size(); + } + + @Override + public void clear() { + backing.forEach(InstanceData::delete); + backing.clear(); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/SelectInstance.java b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/SelectInstance.java new file mode 100644 index 000000000..217b7666f --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/render/backend/instancing/util/SelectInstance.java @@ -0,0 +1,59 @@ +package com.simibubi.create.foundation.render.backend.instancing.util; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import javax.annotation.Nullable; +import com.simibubi.create.foundation.render.backend.instancing.InstanceData; +import com.simibubi.create.foundation.render.backend.instancing.InstancedModel; + +public class SelectInstance { + + final List> models; + + ModelSelector selector; + + private int last = -1; + @Nullable + private D current; + + public SelectInstance(ModelSelector selector) { + this.models = new ArrayList<>(); + this.selector = selector; + } + + public SelectInstance addModel(InstancedModel model) { + models.add(model); + return this; + } + + public SelectInstance update() { + int i = selector.modelIndexToShow(); + + if (i < 0 || i >= models.size()) { + if (current != null) { + current.delete(); + current = null; + } + } else if (i != last) { + if (current != null) current.delete(); + + current = models.get(i).createInstance(); + } + + last = i; + return this; + } + + public Optional get() { + return Optional.ofNullable(current); + } + + public void delete() { + if (current != null) current.delete(); + } + + public interface ModelSelector { + int modelIndexToShow(); + } +}