diff --git a/build.gradle b/build.gradle index c9b86a89a..5af09b855 100644 --- a/build.gradle +++ b/build.gradle @@ -104,10 +104,11 @@ repositories { name = "ModMaven" url = "https://modmaven.dev" }*/ - maven { - // location of the maven for Dynamic Trees - url = 'https://harleyoconnor.com/maven' - } + // Expired SSL cert, prevents building +// maven { +// // location of the maven for Dynamic Trees +// url = 'https://harleyoconnor.com/maven' +// } maven { // location of the maven for Curios API url = "https://maven.theillusivec4.top/" @@ -145,7 +146,7 @@ dependencies { jarJar("com.tterrag.registrate:Registrate:${registrate_version}") { jarJar.ranged(it, '[MC1.19.3-1.1.10,)') } - jarJar("com.jozufozu.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") { + jarJar("dev.engine_room.flywheel:flywheel-forge-${flywheel_minecraft_version}:${flywheel_version}") { jarJar.ranged(it, '[1.0,2.0)') } diff --git a/gradle.properties b/gradle.properties index c17e22e1c..e1cf19259 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,7 +23,7 @@ use_parchment = true # dependency versions registrate_version = MC1.20-1.3.3 flywheel_minecraft_version = 1.20.1 -flywheel_version = 1.0.0-beta-89 +flywheel_version = 1.0.0-beta-97 jei_minecraft_version = 1.20.1 jei_version = 15.2.0.22 curios_minecraft_version = 1.20.1 diff --git a/src/main/java/com/simibubi/create/content/contraptions/actors/harvester/HarvesterActorVisual.java b/src/main/java/com/simibubi/create/content/contraptions/actors/harvester/HarvesterActorVisual.java index 81151d13c..adb578b74 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/actors/harvester/HarvesterActorVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/actors/harvester/HarvesterActorVisual.java @@ -102,9 +102,4 @@ public class HarvesterActorVisual extends ActorVisual { protected double getRotation() { return AngleHelper.angleLerp(AnimationTickHolder.getPartialTicks(), previousRotation, rotation); } - - @Override - public void init(float partialTick) { - - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/actors/psi/PSIActorVisual.java b/src/main/java/com/simibubi/create/content/contraptions/actors/psi/PSIActorVisual.java index 258799fbf..1cb0e4f4a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/actors/psi/PSIActorVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/actors/psi/PSIActorVisual.java @@ -32,9 +32,4 @@ public class PSIActorVisual extends ActorVisual { protected void _delete() { instance.remove(); } - - @Override - public void init(float partialTick) { - - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/actors/psi/PSIVisual.java b/src/main/java/com/simibubi/create/content/contraptions/actors/psi/PSIVisual.java index 2e9490fa2..c871a8137 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/actors/psi/PSIVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/actors/psi/PSIVisual.java @@ -14,16 +14,12 @@ public class PSIVisual extends AbstractBlockEntityVisual e final Axis rotationAxis; final Quaternionf blockOrientation; - public BearingVisual(VisualizationContext context, B blockEntity) { - super(context, blockEntity); + public BearingVisual(VisualizationContext context, B blockEntity, float partialTick) { + super(context, blockEntity, partialTick); Direction facing = blockState.getValue(BlockStateProperties.FACING); rotationAxis = Axis.of(Direction.get(Direction.AxisDirection.POSITIVE, axis).step()); @@ -58,8 +58,8 @@ public class BearingVisual e } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); relight(pos, topInstance); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/bearing/StabilizedBearingVisual.java b/src/main/java/com/simibubi/create/content/contraptions/bearing/StabilizedBearingVisual.java index 9e92a8992..e283bdb41 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/bearing/StabilizedBearingVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/bearing/StabilizedBearingVisual.java @@ -70,9 +70,4 @@ public class StabilizedBearingVisual extends ActorVisual { topInstance.delete(); shaft.delete(); } - - @Override - public void init(float partialTick) { - - } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/chassis/StickerVisual.java b/src/main/java/com/simibubi/create/content/contraptions/chassis/StickerVisual.java index 0969bc796..098be1b02 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/chassis/StickerVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/chassis/StickerVisual.java @@ -26,8 +26,8 @@ public class StickerVisual extends AbstractBlockEntityVisual private final TransformedInstance head; - public StickerVisual(VisualizationContext context, StickerBlockEntity blockEntity) { - super(context, blockEntity); + public StickerVisual(VisualizationContext context, StickerBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); head = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.STICKER_HEAD)).createInstance(); @@ -66,7 +66,7 @@ public class StickerVisual extends AbstractBlockEntityVisual } @Override - public void updateLight() { + public void updateLight(float partialTick) { relight(pos, head); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/elevator/ElevatorPulleyVisual.java b/src/main/java/com/simibubi/create/content/contraptions/elevator/ElevatorPulleyVisual.java index ecd18a8b6..be55b416a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/elevator/ElevatorPulleyVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/elevator/ElevatorPulleyVisual.java @@ -8,8 +8,8 @@ import com.simibubi.create.content.kinetics.base.ShaftVisual; // TODO public class ElevatorPulleyVisual extends ShaftVisual implements SimpleDynamicVisual { - public ElevatorPulleyVisual(VisualizationContext context, ElevatorPulleyBlockEntity blockEntity) { - super(context, blockEntity); + public ElevatorPulleyVisual(VisualizationContext context, ElevatorPulleyBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/contraptions/gantry/GantryCarriageVisual.java b/src/main/java/com/simibubi/create/content/contraptions/gantry/GantryCarriageVisual.java index 4328d7119..767b5453a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/gantry/GantryCarriageVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/gantry/GantryCarriageVisual.java @@ -31,8 +31,8 @@ public class GantryCarriageVisual extends ShaftVisual private float lastAngle = Float.NaN; - public GantryCarriageVisual(VisualizationContext context, GantryCarriageBlockEntity blockEntity) { - super(context, blockEntity); + public GantryCarriageVisual(VisualizationContext context, GantryCarriageBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); gantryCogs = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GANTRY_COGS)) .createInstance(); @@ -98,7 +98,7 @@ public class GantryCarriageVisual extends ShaftVisual } @Override - public void updateLight() { + public void updateLight(float partialTick) { relight(pos, gantryCogs, rotatingModel); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/pulley/AbstractPulleyVisual.java b/src/main/java/com/simibubi/create/content/contraptions/pulley/AbstractPulleyVisual.java index 9538a9e77..88f41ed04 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/pulley/AbstractPulleyVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/pulley/AbstractPulleyVisual.java @@ -2,13 +2,14 @@ package com.simibubi.create.content.contraptions.pulley; import java.util.function.Consumer; +import com.simibubi.create.foundation.utility.flywheel.box.MutableBox; +import com.simibubi.create.foundation.utility.flywheel.light.LightVolume; + import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import dev.engine_room.flywheel.lib.box.MutableBox; import dev.engine_room.flywheel.lib.instance.OrientedInstance; -import dev.engine_room.flywheel.lib.light.LightVolume; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; import com.mojang.math.Axis; import com.simibubi.create.content.kinetics.base.KineticBlockEntity; @@ -34,8 +35,8 @@ public abstract class AbstractPulleyVisual extends private final MutableBox volume = new MutableBox(); private final LightVolume light; - public AbstractPulleyVisual(VisualizationContext dispatcher, T blockEntity) { - super(dispatcher, blockEntity); + public AbstractPulleyVisual(VisualizationContext dispatcher, T blockEntity, float partialTick) { + super(dispatcher, blockEntity, partialTick); rotatingAbout = Direction.get(Direction.AxisDirection.POSITIVE, axis); rotationAxis = Axis.of(rotatingAbout.step()); @@ -109,8 +110,8 @@ public abstract class AbstractPulleyVisual extends } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); light.copyLight(volume); relight(pos, coil); } diff --git a/src/main/java/com/simibubi/create/content/contraptions/pulley/HosePulleyVisual.java b/src/main/java/com/simibubi/create/content/contraptions/pulley/HosePulleyVisual.java index cb048089c..e295bd3bc 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/pulley/HosePulleyVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/pulley/HosePulleyVisual.java @@ -10,8 +10,8 @@ import com.simibubi.create.content.fluids.hosePulley.HosePulleyBlockEntity; public class HosePulleyVisual extends AbstractPulleyVisual { - public HosePulleyVisual(VisualizationContext dispatcher, HosePulleyBlockEntity blockEntity) { - super(dispatcher, blockEntity); + public HosePulleyVisual(VisualizationContext dispatcher, HosePulleyBlockEntity blockEntity, float partialTick) { + super(dispatcher, blockEntity, partialTick); } protected Instancer getRopeModel() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/pulley/RopePulleyVisual.java b/src/main/java/com/simibubi/create/content/contraptions/pulley/RopePulleyVisual.java index 606fc5006..f18ed5223 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/pulley/RopePulleyVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/pulley/RopePulleyVisual.java @@ -11,8 +11,8 @@ import com.simibubi.create.AllPartialModels; import com.simibubi.create.foundation.render.VirtualRenderHelper; public class RopePulleyVisual extends AbstractPulleyVisual { - public RopePulleyVisual(VisualizationContext context, PulleyBlockEntity blockEntity) { - super(context, blockEntity); + public RopePulleyVisual(VisualizationContext context, PulleyBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } protected Instancer getRopeModel() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java index 8286b84ea..d31560822 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java +++ b/src/main/java/com/simibubi/create/content/contraptions/render/ContraptionVisual.java @@ -2,7 +2,12 @@ package com.simibubi.create.content.contraptions.render; import java.util.ArrayList; import java.util.List; -import java.util.function.LongConsumer; + +import dev.engine_room.flywheel.api.visual.LightUpdatedVisual; + +import dev.engine_room.flywheel.api.visual.ShaderLightVisual; +import it.unimi.dsi.fastutil.longs.LongArraySet; +import it.unimi.dsi.fastutil.longs.LongSet; import org.apache.commons.lang3.tuple.MutablePair; @@ -10,7 +15,6 @@ import dev.engine_room.flywheel.api.model.Model; import dev.engine_room.flywheel.api.task.Plan; import dev.engine_room.flywheel.api.visual.BlockEntityVisual; import dev.engine_room.flywheel.api.visual.DynamicVisual; -import dev.engine_room.flywheel.api.visual.LitVisual; import dev.engine_room.flywheel.api.visual.TickableVisual; import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer; import dev.engine_room.flywheel.api.visualization.VisualEmbedding; @@ -44,7 +48,7 @@ import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; import net.minecraftforge.client.model.data.ModelData; -public class ContraptionVisual extends AbstractEntityVisual implements DynamicVisual, TickableVisual, LitVisual { +public class ContraptionVisual extends AbstractEntityVisual implements DynamicVisual, TickableVisual, LightUpdatedVisual, ShaderLightVisual { protected static final int LIGHT_PADDING = 1; protected final VisualEmbedding embedding; @@ -55,18 +59,19 @@ public class ContraptionVisual extends Abst protected VirtualRenderWorld virtualRenderWorld; protected Model model; protected TransformedInstance structure; - protected Notifier notifier; + protected SectionCollector sectionCollector; protected long minSection, maxSection; protected long minBlock, maxBlock; private final PoseStack contraptionMatrix = new PoseStack(); - public ContraptionVisual(VisualizationContext ctx, E entity) { - super(ctx, entity); + public ContraptionVisual(VisualizationContext ctx, E entity, float partialTick) { + super(ctx, entity, partialTick); embedding = ctx.createEmbedding(); + + init(partialTick); } - @Override public void init(float partialTick) { setEmbeddingMatrices(partialTick); @@ -97,7 +102,7 @@ public class ContraptionVisual extends Abst setupActor(actor, partialTick); } - updateLight(); + updateLight(partialTick); } @SuppressWarnings("unchecked") @@ -107,11 +112,9 @@ public class ContraptionVisual extends Abst return; } - Level world = be.getLevel(); + Level level = be.getLevel(); be.setLevel(virtualRenderWorld); - BlockEntityVisual visual = visualizer.createVisual(this.embedding, be); - - visual.init(partialTicks); + BlockEntityVisual visual = visualizer.createVisual(this.embedding, be, partialTicks); children.add(visual); @@ -123,7 +126,7 @@ public class ContraptionVisual extends Abst tickableVisuals.add(tickable, tickable.planTick()); } - be.setLevel(world); + be.setLevel(level); } private void setupActor(MutablePair actor, float partialTick) { @@ -147,8 +150,6 @@ public class ContraptionVisual extends Abst return; } - visual.init(partialTick); - actors.add(visual); } @@ -174,14 +175,14 @@ public class ContraptionVisual extends Abst setEmbeddingMatrices(partialTick); if (hasMovedSections()) { - notifier.notifySectionsChanged(); + sectionCollector.sections(collectLightSections()); } if (hasMovedBlocks()) { // TODO: incremental light collection // TODO: optimize light collection for very large contraptions // by only collecting cuboids that contain faces - updateLight(); + updateLight(partialTick); } } @@ -198,27 +199,11 @@ public class ContraptionVisual extends Abst } @Override - public void updateLight() { - embedding.invalidateLight(); - // FIXME: Some blocks (e.g. large waterwheels) extend well beyond their actual block - // and might have lighting issues here - var boundingBox = entity.getBoundingBox(); - - int minX = minLight(boundingBox.minX); - int minY = minLight(boundingBox.minY); - int minZ = minLight(boundingBox.minZ); - int maxX = maxLight(boundingBox.maxX); - int maxY = maxLight(boundingBox.maxY); - int maxZ = maxLight(boundingBox.maxZ); - - minBlock = BlockPos.asLong(minX, minY, minZ); - maxBlock = BlockPos.asLong(maxX, maxY, maxZ); - - embedding.collectLight(level, minX, minY, minZ, maxX - minX, maxY - minY, maxZ - minZ); + public void updateLight(float partialTick) { + super.update(partialTick); } - @Override - public void collectLightSections(LongConsumer consumer) { + public LongSet collectLightSections() { var boundingBox = entity.getBoundingBox(); var minSectionX = minLightSection(boundingBox.minX); @@ -231,13 +216,17 @@ public class ContraptionVisual extends Abst minSection = SectionPos.asLong(minSectionX, minSectionY, minSectionZ); maxSection = SectionPos.asLong(maxSectionX, maxSectionY, maxSectionZ); + LongSet longSet = new LongArraySet(); + for (int x = 0; x <= maxSectionX - minSectionX; x++) { for (int y = 0; y <= maxSectionY - minSectionY; y++) { for (int z = 0; z <= maxSectionZ - minSectionZ; z++) { - consumer.accept(SectionPos.offset(minSection, x, y, z)); + longSet.add(SectionPos.offset(minSection, x, y, z)); } } } + + return longSet; } protected boolean hasMovedBlocks() { @@ -267,8 +256,8 @@ public class ContraptionVisual extends Abst } @Override - public void initLightSectionNotifier(Notifier notifier) { - this.notifier = notifier; + public void setSectionCollector(SectionCollector collector) { + this.sectionCollector = collector; } @Override diff --git a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankVisual.java b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankVisual.java index d27487a86..f65116970 100644 --- a/src/main/java/com/simibubi/create/content/equipment/armor/BacktankVisual.java +++ b/src/main/java/com/simibubi/create/content/equipment/armor/BacktankVisual.java @@ -7,8 +7,8 @@ import com.simibubi.create.content.kinetics.base.SingleRotatingVisual; public class BacktankVisual extends SingleRotatingVisual { - public BacktankVisual(VisualizationContext context, BacktankBlockEntity blockEntity) { - super(context, blockEntity); + public BacktankVisual(VisualizationContext context, BacktankBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolBoxVisual.java b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolBoxVisual.java index 1220d09c0..d4d62ab4a 100644 --- a/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolBoxVisual.java +++ b/src/main/java/com/simibubi/create/content/equipment/toolbox/ToolBoxVisual.java @@ -19,25 +19,20 @@ import net.minecraft.core.Direction; public class ToolBoxVisual extends AbstractBlockEntityVisual implements SimpleDynamicVisual { private final Direction facing; - private TransformedInstance lid; - private TransformedInstance[] drawers; + private final TransformedInstance lid; + private final TransformedInstance[] drawers; - public ToolBoxVisual(VisualizationContext context, ToolboxBlockEntity blockEntity) { - super(context, blockEntity); + public ToolBoxVisual(VisualizationContext context, ToolboxBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); facing = blockState.getValue(ToolboxBlock.FACING) .getOpposite(); - } - @Override - public void init(float pt) { Instancer drawerModel = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_DRAWER)); drawers = new TransformedInstance[]{drawerModel.createInstance(), drawerModel.createInstance()}; lid = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.TOOLBOX_LIDS.get(blockEntity.getColor()))) .createInstance(); - - super.init(pt); } @Override @@ -78,7 +73,7 @@ public class ToolBoxVisual extends AbstractBlockEntityVisual } @Override - public void updateLight() { + public void updateLight(float partialTick) { relight(pos, drawers); relight(pos, lid); } diff --git a/src/main/java/com/simibubi/create/content/fluids/pipes/valve/FluidValveVisual.java b/src/main/java/com/simibubi/create/content/fluids/pipes/valve/FluidValveVisual.java index 2e57541ce..3763824b1 100644 --- a/src/main/java/com/simibubi/create/content/fluids/pipes/valve/FluidValveVisual.java +++ b/src/main/java/com/simibubi/create/content/fluids/pipes/valve/FluidValveVisual.java @@ -26,8 +26,8 @@ public class FluidValveVisual extends ShaftVisual impleme protected final double yRot; protected final int pointerRotationOffset; - public FluidValveVisual(VisualizationContext dispatcher, FluidValveBlockEntity blockEntity) { - super(dispatcher, blockEntity); + public FluidValveVisual(VisualizationContext dispatcher, FluidValveBlockEntity blockEntity, float partialTick) { + super(dispatcher, blockEntity, partialTick); Direction facing = blockState.getValue(FluidValveBlock.FACING); @@ -75,8 +75,8 @@ public class FluidValveVisual extends ShaftVisual impleme } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); relight(pos, pointer); } diff --git a/src/main/java/com/simibubi/create/content/fluids/pump/PumpCogVisual.java b/src/main/java/com/simibubi/create/content/fluids/pump/PumpCogVisual.java index 7dce27728..352df4be0 100644 --- a/src/main/java/com/simibubi/create/content/fluids/pump/PumpCogVisual.java +++ b/src/main/java/com/simibubi/create/content/fluids/pump/PumpCogVisual.java @@ -12,8 +12,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class PumpCogVisual extends SingleRotatingVisual { - public PumpCogVisual(VisualizationContext context, PumpBlockEntity blockEntity) { - super(context, blockEntity); + public PumpCogVisual(VisualizationContext context, PumpBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/BackHalfShaftVisual.java b/src/main/java/com/simibubi/create/content/kinetics/base/BackHalfShaftVisual.java index 4f04744ac..74c748fef 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/BackHalfShaftVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/BackHalfShaftVisual.java @@ -6,8 +6,8 @@ import net.minecraft.core.Direction; import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class BackHalfShaftVisual extends HalfShaftVisual { - public BackHalfShaftVisual(VisualizationContext context, T blockEntity) { - super(context, blockEntity); + public BackHalfShaftVisual(VisualizationContext context, T blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/HalfShaftVisual.java b/src/main/java/com/simibubi/create/content/kinetics/base/HalfShaftVisual.java index 61b5dc887..f1d70425b 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/HalfShaftVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/HalfShaftVisual.java @@ -9,8 +9,8 @@ import net.minecraft.core.Direction; import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class HalfShaftVisual extends SingleRotatingVisual { - public HalfShaftVisual(VisualizationContext context, T blockEntity) { - super(context, blockEntity); + public HalfShaftVisual(VisualizationContext context, T blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/HorizontalHalfShaftVisual.java b/src/main/java/com/simibubi/create/content/kinetics/base/HorizontalHalfShaftVisual.java index 1ef78ce73..80b76c8c7 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/HorizontalHalfShaftVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/HorizontalHalfShaftVisual.java @@ -7,8 +7,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class HorizontalHalfShaftVisual extends HalfShaftVisual { - public HorizontalHalfShaftVisual(VisualizationContext context, T blockEntity) { - super(context, blockEntity); + public HorizontalHalfShaftVisual(VisualizationContext context, T blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/KineticBlockEntityVisual.java b/src/main/java/com/simibubi/create/content/kinetics/base/KineticBlockEntityVisual.java index b98f828e4..388d188f8 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/KineticBlockEntityVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/KineticBlockEntityVisual.java @@ -14,8 +14,8 @@ public abstract class KineticBlockEntityVisual ext protected final Direction.Axis axis; - public KineticBlockEntityVisual(VisualizationContext context, T blockEntity) { - super(context, blockEntity); + public KineticBlockEntityVisual(VisualizationContext context, T blockEntity, float partialTick) { + super(context, blockEntity, partialTick); axis = (blockState.getBlock() instanceof IRotate irotate) ? irotate.getRotationAxis(blockState) : Axis.Y; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/KineticInstance.java b/src/main/java/com/simibubi/create/content/kinetics/base/KineticInstance.java index 755395786..7d01abaf9 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/KineticInstance.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/KineticInstance.java @@ -46,13 +46,13 @@ public class KineticInstance extends ColoredLitInstance { if (blockEntity.hasNetwork()) { setColor(Color.generateFromLong(blockEntity.network)); }else { - setColor(0xFF, 0xFF, 0xFF); + color(0xFF, 0xFF, 0xFF); } return this; } public KineticInstance setColor(Color c) { - setColor(c.getRed(), c.getGreen(), c.getBlue()); + color(c.getRed(), c.getGreen(), c.getBlue()); return this; } diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/ShaftVisual.java b/src/main/java/com/simibubi/create/content/kinetics/base/ShaftVisual.java index 1ee8ca5f9..5d7cd588b 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/ShaftVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/ShaftVisual.java @@ -6,8 +6,8 @@ import com.simibubi.create.foundation.render.VirtualRenderHelper; public class ShaftVisual extends SingleRotatingVisual { - public ShaftVisual(VisualizationContext context, T blockEntity) { - super(context, blockEntity); + public ShaftVisual(VisualizationContext context, T blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/base/SingleRotatingVisual.java b/src/main/java/com/simibubi/create/content/kinetics/base/SingleRotatingVisual.java index 4e41dcd5e..9a032359f 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/base/SingleRotatingVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/base/SingleRotatingVisual.java @@ -13,16 +13,14 @@ public class SingleRotatingVisual extends KineticB protected RotatingInstance rotatingModel; - public SingleRotatingVisual(VisualizationContext context, T blockEntity) { - super(context, blockEntity); + public SingleRotatingVisual(VisualizationContext context, T blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } - @Override public void init(float pt) { rotatingModel = instancerProvider.instancer(AllInstanceTypes.ROTATING, model()) .createInstance(); setup(rotatingModel); - super.init(pt); } @Override @@ -31,7 +29,7 @@ public class SingleRotatingVisual extends KineticB } @Override - public void updateLight() { + public void updateLight(float partialTick) { relight(pos, rotatingModel); } diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlockEntity.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlockEntity.java index 57cf08fa9..2746bebd6 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlockEntity.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltBlockEntity.java @@ -12,8 +12,6 @@ import java.util.Map; import java.util.Optional; import java.util.function.Function; -import dev.engine_room.flywheel.lib.box.Box; -import dev.engine_room.flywheel.lib.box.MutableBox; import com.simibubi.create.AllBlocks; import com.simibubi.create.content.kinetics.base.IRotate; import com.simibubi.create.content.kinetics.base.KineticBlockEntity; @@ -30,6 +28,9 @@ import com.simibubi.create.content.logistics.tunnel.BrassTunnelBlockEntity; import com.simibubi.create.foundation.blockEntity.behaviour.BlockEntityBehaviour; import com.simibubi.create.foundation.utility.NBTHelper; +import com.simibubi.create.foundation.utility.flywheel.box.Box; +import com.simibubi.create.foundation.utility.flywheel.box.MutableBox; + import net.minecraft.client.renderer.LightTexture; import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos.MutableBlockPos; diff --git a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltVisual.java b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltVisual.java index 1d7d930f6..eb82bc880 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/belt/BeltVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/belt/BeltVisual.java @@ -3,6 +3,8 @@ package com.simibubi.create.content.kinetics.belt; import java.util.ArrayList; import java.util.function.Consumer; +import dev.engine_room.flywheel.lib.instance.FlatLit; + import org.joml.Quaternionf; import dev.engine_room.flywheel.api.instance.Instance; @@ -38,8 +40,8 @@ public class BeltVisual extends KineticBlockEntityVisual { protected ArrayList keys; protected RotatingInstance pulleyKey; - public BeltVisual(VisualizationContext context, BeltBlockEntity blockEntity) { - super(context, blockEntity); + public BeltVisual(VisualizationContext context, BeltBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); if (!AllBlocks.BELT.has(blockState)) return; @@ -99,8 +101,8 @@ public class BeltVisual extends KineticBlockEntityVisual { } @Override - public void updateLight() { - relight(pos, keys.stream()); + public void updateLight(float partialTick) { + relight(pos, keys.toArray(FlatLit[]::new)); if (pulleyKey != null) relight(pos, pulleyKey); } diff --git a/src/main/java/com/simibubi/create/content/kinetics/crafter/ShaftlessCogwheelVisual.java b/src/main/java/com/simibubi/create/content/kinetics/crafter/ShaftlessCogwheelVisual.java index 7e2aa99d1..f5db9293d 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/crafter/ShaftlessCogwheelVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/crafter/ShaftlessCogwheelVisual.java @@ -13,8 +13,8 @@ import net.minecraft.core.Direction; public class ShaftlessCogwheelVisual extends SingleRotatingVisual { - public ShaftlessCogwheelVisual(VisualizationContext context, KineticBlockEntity blockEntity) { - super(context, blockEntity); + public ShaftlessCogwheelVisual(VisualizationContext context, KineticBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/crank/HandCrankVisual.java b/src/main/java/com/simibubi/create/content/kinetics/crank/HandCrankVisual.java index e5549c9e6..4a458de17 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/crank/HandCrankVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/crank/HandCrankVisual.java @@ -16,15 +16,22 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class HandCrankVisual extends SingleRotatingVisual implements SimpleDynamicVisual { - private TransformedInstance crank; - private Direction facing; + private final TransformedInstance crank; + private final Direction facing; - public HandCrankVisual(VisualizationContext modelManager, HandCrankBlockEntity blockEntity) { - super(modelManager, blockEntity); + public HandCrankVisual(VisualizationContext modelManager, HandCrankBlockEntity blockEntity, float partialTick) { + super(modelManager, blockEntity, partialTick); facing = blockState.getValue(BlockStateProperties.FACING); Model model = blockEntity.getRenderedHandleInstance(); crank = instancerProvider.instancer(InstanceTypes.TRANSFORMED, model) .createInstance(); + + rotateCrank(partialTick); + + if (blockEntity.shouldRenderShaft()) + setup(rotatingModel); + + updateLight(partialTick); } @Override @@ -47,17 +54,6 @@ public class HandCrankVisual extends SingleRotatingVisual .setChanged(); } - @Override - public void init(float pt) { - rotateCrank(pt); - - // FIXME: need to call super.super.init here - if (blockEntity.shouldRenderShaft()) - super.init(pt); - - updateLight(); - } - @Override protected void _delete() { if (blockEntity.shouldRenderShaft()) @@ -73,9 +69,9 @@ public class HandCrankVisual extends SingleRotatingVisual } @Override - public void updateLight() { + public void updateLight(float partialTick) { if (blockEntity.shouldRenderShaft()) - super.updateLight(); + super.updateLight(partialTick); if (crank != null) relight(pos, crank); } diff --git a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerActorVisual.java b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerActorVisual.java index 0ce7ad3b1..88e1f03ec 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerActorVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerActorVisual.java @@ -124,9 +124,4 @@ public class DeployerActorVisual extends ActorVisual { hand.delete(); shaft.delete(); } - - @Override - public void init(float partialTick) { - - } } diff --git a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerVisual.java b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerVisual.java index 3e5afc77e..001d28d96 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/deployer/DeployerVisual.java @@ -41,8 +41,8 @@ public class DeployerVisual extends ShaftVisual implements PartialModel currentHand; float progress; - public DeployerVisual(VisualizationContext context, DeployerBlockEntity blockEntity) { - super(context, blockEntity); + public DeployerVisual(VisualizationContext context, DeployerBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); facing = blockState.getValue(FACING); @@ -57,16 +57,11 @@ public class DeployerVisual extends ShaftVisual implements currentHand = this.blockEntity.getHandPose(); hand = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(currentHand)).createInstance(); - } - @Override - public void init(float pt) { - progress = getProgress(pt); + progress = getProgress(partialTick); updateRotation(pole, hand, yRot, xRot, zRot); updatePosition(); - - super.init(pt); - } + } @Override public void tick(TickableVisual.Context context) { @@ -91,8 +86,8 @@ public class DeployerVisual extends ShaftVisual implements } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); relight(pos, hand, pole); } diff --git a/src/main/java/com/simibubi/create/content/kinetics/drill/DrillActorVisual.java b/src/main/java/com/simibubi/create/content/kinetics/drill/DrillActorVisual.java index 4912fe5fb..f42444f5e 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/drill/DrillActorVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/drill/DrillActorVisual.java @@ -66,9 +66,4 @@ public class DrillActorVisual extends ActorVisual { protected void _delete() { drillHead.delete(); } - - @Override - public void init(float partialTick) { - - } } diff --git a/src/main/java/com/simibubi/create/content/kinetics/drill/DrillVisual.java b/src/main/java/com/simibubi/create/content/kinetics/drill/DrillVisual.java index 5f20113e5..c3fde3d4e 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/drill/DrillVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/drill/DrillVisual.java @@ -11,8 +11,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class DrillVisual extends SingleRotatingVisual { - public DrillVisual(VisualizationContext context, DrillBlockEntity blockEntity) { - super(context, blockEntity); + public DrillVisual(VisualizationContext context, DrillBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/fan/FanVisual.java b/src/main/java/com/simibubi/create/content/kinetics/fan/FanVisual.java index 4a9fc526c..ec6c782cb 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/fan/FanVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/fan/FanVisual.java @@ -23,8 +23,8 @@ public class FanVisual extends KineticBlockEntityVisual { final Direction direction; private final Direction opposite; - public FanVisual(VisualizationContext context, EncasedFanBlockEntity blockEntity) { - super(context, blockEntity); + public FanVisual(VisualizationContext context, EncasedFanBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); direction = blockState.getValue(FACING); @@ -53,7 +53,7 @@ public class FanVisual extends KineticBlockEntityVisual { } @Override - public void updateLight() { + public void updateLight(float partialTick) { BlockPos behind = pos.relative(opposite); relight(behind, shaft); diff --git a/src/main/java/com/simibubi/create/content/kinetics/flywheel/FlywheelVisual.java b/src/main/java/com/simibubi/create/content/kinetics/flywheel/FlywheelVisual.java index f712eda48..0f7d332c5 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/flywheel/FlywheelVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/flywheel/FlywheelVisual.java @@ -24,8 +24,8 @@ public class FlywheelVisual extends KineticBlockEntityVisual implemen protected final PoseStack ms = new PoseStack(); - protected GaugeVisual(VisualizationContext context, GaugeBlockEntity blockEntity) { - super(context, blockEntity); + protected GaugeVisual(VisualizationContext context, GaugeBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); + + init(partialTick); } - @Override - public void init(float pt) { + public void init(float partialTick) { GaugeBlock gaugeBlock = (GaugeBlock) blockState.getBlock(); Instancer dialModel = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.GAUGE_DIAL)); @@ -54,8 +56,6 @@ public abstract class GaugeVisual extends ShaftVisual implemen face.setupTransform(msr, progress); } - - super.init(pt); } private DialFace makeFace(Direction face, Instancer dialModel, Instancer headModel) { @@ -77,11 +77,11 @@ public abstract class GaugeVisual extends ShaftVisual implemen } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); relight(pos, faces.stream() - .flatMap(Couple::stream)); + .flatMap(Couple::stream).toArray(FlatLit[]::new)); } @Override @@ -155,8 +155,8 @@ public abstract class GaugeVisual extends ShaftVisual implemen } public static class Speed extends GaugeVisual { - public Speed(VisualizationContext context, GaugeBlockEntity blockEntity) { - super(context, blockEntity); + public Speed(VisualizationContext context, GaugeBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override @@ -166,8 +166,8 @@ public abstract class GaugeVisual extends ShaftVisual implemen } public static class Stress extends GaugeVisual { - public Stress(VisualizationContext context, GaugeBlockEntity blockEntity) { - super(context, blockEntity); + public Stress(VisualizationContext context, GaugeBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/gearbox/GearboxVisual.java b/src/main/java/com/simibubi/create/content/kinetics/gearbox/GearboxVisual.java index e37c03321..be8dfa0ad 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/gearbox/GearboxVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/gearbox/GearboxVisual.java @@ -7,6 +7,7 @@ import java.util.function.Consumer; import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.AbstractInstance; +import dev.engine_room.flywheel.lib.instance.FlatLit; import dev.engine_room.flywheel.lib.model.Models; import com.simibubi.create.AllPartialModels; import com.simibubi.create.content.kinetics.base.KineticBlockEntityVisual; @@ -24,8 +25,8 @@ public class GearboxVisual extends KineticBlockEntityVisual protected final EnumMap keys; protected Direction sourceFacing; - public GearboxVisual(VisualizationContext context, GearboxBlockEntity blockEntity) { - super(context, blockEntity); + public GearboxVisual(VisualizationContext context, GearboxBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); keys = new EnumMap<>(Direction.class); @@ -87,8 +88,8 @@ public class GearboxVisual extends KineticBlockEntityVisual } @Override - public void updateLight() { - relight(pos, keys.values().stream()); + public void updateLight(float partialTick) { + relight(pos, keys.values().toArray(FlatLit[]::new)); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmVisual.java b/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmVisual.java index f46e67ed8..e76c62493 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/mechanicalArm/ArmVisual.java @@ -9,6 +9,7 @@ import dev.engine_room.flywheel.api.model.Model; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.AbstractInstance; +import dev.engine_room.flywheel.lib.instance.FlatLit; import dev.engine_room.flywheel.lib.instance.InstanceTypes; import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.model.Models; @@ -45,8 +46,8 @@ public class ArmVisual extends SingleRotatingVisual implements S private float upperArmAngle = Float.NaN; private float headAngle = Float.NaN; - public ArmVisual(VisualizationContext context, ArmBlockEntity blockEntity) { - super(context, blockEntity); + public ArmVisual(VisualizationContext context, ArmBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); base = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ARM_BASE)) .createInstance(); @@ -131,12 +132,12 @@ public class ArmVisual extends SingleRotatingVisual implements S ArmRenderer.transformLowerArm(msr, lowerArmAngle); lowerBody.setTransform(msLocal) - .setColor(color) + .color(color) .setChanged(); ArmRenderer.transformUpperArm(msr, upperArmAngle); upperBody.setTransform(msLocal) - .setColor(color) + .color(color) .setChanged(); ArmRenderer.transformHead(msr, headAngle); @@ -177,15 +178,15 @@ public class ArmVisual extends SingleRotatingVisual implements S claw = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(blockEntity.goggles ? AllPartialModels.ARM_CLAW_BASE_GOGGLES : AllPartialModels.ARM_CLAW_BASE)) .createInstance(); models.add(claw); - updateLight(); + updateLight(pt); animateArm(); } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); - relight(pos, models.stream()); + relight(pos, models.toArray(FlatLit[]::new)); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/millstone/MillstoneCogVisual.java b/src/main/java/com/simibubi/create/content/kinetics/millstone/MillstoneCogVisual.java index 257fd5a06..f934bf5e2 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/millstone/MillstoneCogVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/millstone/MillstoneCogVisual.java @@ -8,8 +8,8 @@ import com.simibubi.create.content.kinetics.base.SingleRotatingVisual; public class MillstoneCogVisual extends SingleRotatingVisual { - public MillstoneCogVisual(VisualizationContext context, MillstoneBlockEntity blockEntity) { - super(context, blockEntity); + public MillstoneCogVisual(VisualizationContext context, MillstoneBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/mixer/MixerVisual.java b/src/main/java/com/simibubi/create/content/kinetics/mixer/MixerVisual.java index 23b82a52d..5305f2001 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/mixer/MixerVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/mixer/MixerVisual.java @@ -23,8 +23,8 @@ public class MixerVisual extends EncasedCogVisual implements SimpleDynamicVisual private final OrientedInstance mixerPole; private final MechanicalMixerBlockEntity mixer; - public MixerVisual(VisualizationContext context, MechanicalMixerBlockEntity blockEntity) { - super(context, blockEntity, false); + public MixerVisual(VisualizationContext context, MechanicalMixerBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, false, partialTick); this.mixer = blockEntity; mixerHead = instancerProvider.instancer(AllInstanceTypes.ROTATING, Models.partial(AllPartialModels.MECHANICAL_MIXER_HEAD)) @@ -34,13 +34,8 @@ public class MixerVisual extends EncasedCogVisual implements SimpleDynamicVisual mixerPole = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_MIXER_POLE)) .createInstance(); - } - @Override - public void init(float pt) { - super.init(pt); - - animate(pt); + animate(partialTick); } @Override @@ -76,8 +71,8 @@ public class MixerVisual extends EncasedCogVisual implements SimpleDynamicVisual } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); relight(pos.below(), mixerHead); relight(pos, mixerPole); diff --git a/src/main/java/com/simibubi/create/content/kinetics/press/PressVisual.java b/src/main/java/com/simibubi/create/content/kinetics/press/PressVisual.java index c9aff6fa4..91adb2a23 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/press/PressVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/press/PressVisual.java @@ -20,8 +20,8 @@ public class PressVisual extends ShaftVisual impleme private final OrientedInstance pressHead; - public PressVisual(VisualizationContext context, MechanicalPressBlockEntity blockEntity) { - super(context, blockEntity); + public PressVisual(VisualizationContext context, MechanicalPressBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); pressHead = instancerProvider.instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.MECHANICAL_PRESS_HEAD)) .createInstance(); @@ -30,13 +30,8 @@ public class PressVisual extends ShaftVisual impleme .rotationDegrees(AngleHelper.horizontalAngle(blockState.getValue(MechanicalPressBlock.HORIZONTAL_FACING))); pressHead.setRotation(q); - } - @Override - public void init(float pt) { - super.init(pt); - - transformModels(pt); + transformModels(partialTick); } @Override @@ -59,8 +54,8 @@ public class PressVisual extends ShaftVisual impleme } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); relight(pos, pressHead); } diff --git a/src/main/java/com/simibubi/create/content/kinetics/saw/SawVisual.java b/src/main/java/com/simibubi/create/content/kinetics/saw/SawVisual.java index ec84c8bef..418e619fc 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/saw/SawVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/saw/SawVisual.java @@ -14,8 +14,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; public class SawVisual extends SingleRotatingVisual { - public SawVisual(VisualizationContext context, SawBlockEntity blockEntity) { - super(context, blockEntity); + public SawVisual(VisualizationContext context, SawBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); } @Override diff --git a/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/BracketedKineticBlockEntityVisual.java b/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/BracketedKineticBlockEntityVisual.java index 7fb944dd6..62fb81b06 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/BracketedKineticBlockEntityVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/simpleRelays/BracketedKineticBlockEntityVisual.java @@ -24,12 +24,13 @@ public class BracketedKineticBlockEntityVisual extends SingleRotatingVisual { - private boolean large; + private final boolean large; protected RotatingInstance rotatingModel; protected Optional rotatingTopShaft; protected Optional rotatingBottomShaft; - public static EncasedCogVisual small(VisualizationContext modelManager, KineticBlockEntity blockEntity) { - return new EncasedCogVisual(modelManager, blockEntity, false); + public static EncasedCogVisual small(VisualizationContext modelManager, KineticBlockEntity blockEntity, float partialTick) { + return new EncasedCogVisual(modelManager, blockEntity, false, partialTick); } - public static EncasedCogVisual large(VisualizationContext modelManager, KineticBlockEntity blockEntity) { - return new EncasedCogVisual(modelManager, blockEntity, true); + public static EncasedCogVisual large(VisualizationContext modelManager, KineticBlockEntity blockEntity, float partialTick) { + return new EncasedCogVisual(modelManager, blockEntity, true, partialTick); } - public EncasedCogVisual(VisualizationContext modelManager, KineticBlockEntity blockEntity, boolean large) { - super(modelManager, blockEntity); + public EncasedCogVisual(VisualizationContext modelManager, KineticBlockEntity blockEntity, boolean large, float partialTick) { + super(modelManager, blockEntity, partialTick); this.large = large; + + init(partialTick); } - @Override - public void init(float pt) { + public void init(float partialTick) { var instancer = instancerProvider.instancer(AllInstanceTypes.ROTATING, getCogModel()); rotatingModel = setup(instancer.createInstance()); @@ -72,8 +73,6 @@ public class EncasedCogVisual extends KineticBlockEntityVisual relight(pos, d)); rotatingBottomShaft.ifPresent(d -> relight(pos, d)); diff --git a/src/main/java/com/simibubi/create/content/kinetics/steamEngine/SteamEngineVisual.java b/src/main/java/com/simibubi/create/content/kinetics/steamEngine/SteamEngineVisual.java index 84056e422..bb36fefea 100644 --- a/src/main/java/com/simibubi/create/content/kinetics/steamEngine/SteamEngineVisual.java +++ b/src/main/java/com/simibubi/create/content/kinetics/steamEngine/SteamEngineVisual.java @@ -24,8 +24,8 @@ public class SteamEngineVisual extends AbstractBlockEntityVisual keys; - public SplitShaftVisual(VisualizationContext modelManager, SplitShaftBlockEntity blockEntity) { - super(modelManager, blockEntity); + public SplitShaftVisual(VisualizationContext modelManager, SplitShaftBlockEntity blockEntity, float partialTick) { + super(modelManager, blockEntity, partialTick); keys = new ArrayList<>(2); @@ -52,8 +53,8 @@ public class SplitShaftVisual extends KineticBlockEntityVisual extends KineticBl protected BlockState lastMaterial; protected RotatingInstance rotatingModel; - public WaterWheelVisual(VisualizationContext context, T blockEntity, boolean large) { - super(context, blockEntity); + public WaterWheelVisual(VisualizationContext context, T blockEntity, boolean large, float partialTick) { + super(context, blockEntity, partialTick); this.large = large; - } - public static WaterWheelVisual standard(VisualizationContext context, T blockEntity) { - return new WaterWheelVisual<>(context, blockEntity, false); - } - - public static WaterWheelVisual large(VisualizationContext context, T blockEntity) { - return new WaterWheelVisual<>(context, blockEntity, true); - } - - @Override - public void init(float pt) { setupInstance(); - super.init(pt); + } + + public static WaterWheelVisual standard(VisualizationContext context, T blockEntity, float partialTick) { + return new WaterWheelVisual<>(context, blockEntity, false, partialTick); + } + + public static WaterWheelVisual large(VisualizationContext context, T blockEntity, float partialTick) { + return new WaterWheelVisual<>(context, blockEntity, true, partialTick); } private void setupInstance() { @@ -62,7 +58,7 @@ public class WaterWheelVisual extends KineticBl } @Override - public void updateLight() { + public void updateLight(float partialTick) { relight(pos, rotatingModel); } diff --git a/src/main/java/com/simibubi/create/content/logistics/depot/EjectorVisual.java b/src/main/java/com/simibubi/create/content/logistics/depot/EjectorVisual.java index 27c762e8b..27c2aaeef 100644 --- a/src/main/java/com/simibubi/create/content/logistics/depot/EjectorVisual.java +++ b/src/main/java/com/simibubi/create/content/logistics/depot/EjectorVisual.java @@ -18,17 +18,12 @@ public class EjectorVisual extends ShaftVisual implements Si private float lastProgress = Float.NaN; - public EjectorVisual(VisualizationContext dispatcher, EjectorBlockEntity blockEntity) { - super(dispatcher, blockEntity); + public EjectorVisual(VisualizationContext dispatcher, EjectorBlockEntity blockEntity, float partialTick) { + super(dispatcher, blockEntity, partialTick); plate = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.EJECTOR_TOP)).createInstance(); - } - @Override - public void init(float pt) { - pivotPlate(getLidProgress(pt)); - - super.init(pt); + pivotPlate(getLidProgress(partialTick)); } @Override @@ -44,8 +39,8 @@ public class EjectorVisual extends ShaftVisual implements Si } @Override - public void updateLight() { - super.updateLight(); + public void updateLight(float partialTick) { + super.updateLight(partialTick); relight(pos, plate); } diff --git a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelVisual.java b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelVisual.java index cf67251b1..9cebffcfc 100644 --- a/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelVisual.java +++ b/src/main/java/com/simibubi/create/content/logistics/funnel/FunnelVisual.java @@ -8,6 +8,7 @@ import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.AbstractInstance; +import dev.engine_room.flywheel.lib.instance.FlatLit; import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.model.baked.PartialModel; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; @@ -24,8 +25,8 @@ public class FunnelVisual extends AbstractBlockEntityVisual i private final ArrayList flaps; - public FunnelVisual(VisualizationContext context, FunnelBlockEntity blockEntity) { - super(context, blockEntity); + public FunnelVisual(VisualizationContext context, FunnelBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); flaps = new ArrayList<>(4); @@ -76,9 +77,9 @@ public class FunnelVisual extends AbstractBlockEntityVisual i } @Override - public void updateLight() { + public void updateLight(float partialTick) { if (flaps != null) - relight(pos, flaps.stream()); + relight(pos, flaps.toArray(FlatLit[]::new)); } @Override diff --git a/src/main/java/com/simibubi/create/content/logistics/tunnel/BeltTunnelVisual.java b/src/main/java/com/simibubi/create/content/logistics/tunnel/BeltTunnelVisual.java index 5690edf67..452a1d669 100644 --- a/src/main/java/com/simibubi/create/content/logistics/tunnel/BeltTunnelVisual.java +++ b/src/main/java/com/simibubi/create/content/logistics/tunnel/BeltTunnelVisual.java @@ -11,6 +11,7 @@ import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.AbstractInstance; +import dev.engine_room.flywheel.lib.instance.FlatLit; import dev.engine_room.flywheel.lib.model.Models; import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; @@ -26,8 +27,10 @@ public class BeltTunnelVisual extends AbstractBlockEntityVisual> tunnelFlaps = new EnumMap<>(Direction.class); - public BeltTunnelVisual(VisualizationContext context, BeltTunnelBlockEntity blockEntity) { - super(context, blockEntity); + public BeltTunnelVisual(VisualizationContext context, BeltTunnelBlockEntity blockEntity, float partialTick) { + super(context, blockEntity, partialTick); + + setupFlaps(partialTick); } private void setupFlaps(float partialTick) { @@ -69,13 +72,6 @@ public class BeltTunnelVisual extends AbstractBlockEntityVisual bogeys; private Couple bogeyHidden; - public CarriageContraptionVisual(VisualizationContext context, CarriageContraptionEntity entity) { - super(context, entity); + public CarriageContraptionVisual(VisualizationContext context, CarriageContraptionEntity entity, float partialTick) { + super(context, entity, partialTick); bogeyHidden = Couple.create(() -> false); entity.bindInstance(this); } @@ -33,7 +33,7 @@ public class CarriageContraptionVisual extends ContraptionVisual bogey.getStyle() .createVisual(bogey, bogey.type.getSize(), manager), visualizationContext); - updateLight(); + updateLight(pt); } super.init(pt); @@ -86,8 +86,8 @@ public class CarriageContraptionVisual extends ContraptionVisual { - private List visuals; + private final List visuals; - public TrackVisual(VisualizationContext context, TrackBlockEntity track) { - super(context, track); - } + public TrackVisual(VisualizationContext context, TrackBlockEntity track, float partialTick) { + super(context, track, partialTick); - @Override - public void init(float partialTick) { visuals = blockEntity.connections.values() .stream() .map(this::createInstance) .filter(Objects::nonNull) .toList(); - - super.init(partialTick); } @Override @@ -53,12 +51,11 @@ public class TrackVisual extends AbstractBlockEntityVisual { return; _delete(); - init(pt); - notifier.notifySectionsChanged(); + lightSections.sections(collectLightSections()); } @Override - public void updateLight() { + public void updateLight(float partialTick) { if (visuals == null) return; visuals.forEach(BezierTrackVisual::updateLight); @@ -78,10 +75,11 @@ public class TrackVisual extends AbstractBlockEntityVisual { visuals.forEach(BezierTrackVisual::delete); } - @Override - public void collectLightSections(LongConsumer consumer) { + public LongSet collectLightSections() { + LongSet longSet = new LongArraySet(); + if (blockEntity.connections.isEmpty()) { - return; + return LongSet.of(); } int minX = Integer.MAX_VALUE; int minY = Integer.MAX_VALUE; @@ -99,7 +97,9 @@ public class TrackVisual extends AbstractBlockEntityVisual { } SectionPos.betweenClosedStream(SectionPos.blockToSectionCoord(minX), SectionPos.blockToSectionCoord(minY), SectionPos.blockToSectionCoord(minZ), SectionPos.blockToSectionCoord(maxX), SectionPos.blockToSectionCoord(maxY), SectionPos.blockToSectionCoord(maxZ)) .mapToLong(SectionPos::asLong) - .forEach(consumer); + .forEach(longSet::add); + + return longSet; } @Override diff --git a/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java b/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java index c11828e17..9d0fa8697 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java @@ -36,8 +36,8 @@ public class AllInstanceTypes { MemoryUtil.memPutByte(ptr + 1, instance.g); MemoryUtil.memPutByte(ptr + 2, instance.b); MemoryUtil.memPutByte(ptr + 3, instance.a); - MemoryUtil.memPutShort(ptr + 4, (short) (instance.packedLight & 0xFFFF)); - MemoryUtil.memPutShort(ptr + 6, (short) (instance.packedLight >> 16 & 0xFFFF)); + MemoryUtil.memPutShort(ptr + 4, (short) (instance.light & 0xFFFF)); + MemoryUtil.memPutShort(ptr + 6, (short) (instance.light >> 16 & 0xFFFF)); MemoryUtil.memPutInt(ptr + 8, instance.overlay); MemoryUtil.memPutFloat(ptr + 12, instance.x); MemoryUtil.memPutFloat(ptr + 16, instance.y); @@ -70,8 +70,8 @@ public class AllInstanceTypes { MemoryUtil.memPutByte(ptr + 1, instance.g); MemoryUtil.memPutByte(ptr + 2, instance.b); MemoryUtil.memPutByte(ptr + 3, instance.a); - MemoryUtil.memPutShort(ptr + 4, (short) (instance.packedLight & 0xFFFF)); - MemoryUtil.memPutShort(ptr + 6, (short) (instance.packedLight >> 16 & 0xFFFF)); + MemoryUtil.memPutShort(ptr + 4, (short) (instance.light & 0xFFFF)); + MemoryUtil.memPutShort(ptr + 6, (short) (instance.light >> 16 & 0xFFFF)); MemoryUtil.memPutInt(ptr + 8, instance.overlay); MemoryUtil.memPutFloat(ptr + 12, instance.x); MemoryUtil.memPutFloat(ptr + 16, instance.y); diff --git a/src/main/java/com/simibubi/create/foundation/utility/flywheel/box/Box.java b/src/main/java/com/simibubi/create/foundation/utility/flywheel/box/Box.java new file mode 100644 index 000000000..2259c5f73 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/flywheel/box/Box.java @@ -0,0 +1,142 @@ +package com.simibubi.create.foundation.utility.flywheel.box; + +import net.minecraft.util.Mth; +import net.minecraft.world.phys.AABB; + +public interface Box { + int getMinX(); + + int getMinY(); + + int getMinZ(); + + int getMaxX(); + + int getMaxY(); + + int getMaxZ(); + + default int sizeX() { + return getMaxX() - getMinX(); + } + + default int sizeY() { + return getMaxY() - getMinY(); + } + + default int sizeZ() { + return getMaxZ() - getMinZ(); + } + + default int volume() { + return sizeX() * sizeY() * sizeZ(); + } + + default boolean isEmpty() { + // if any dimension has side length 0 this box contains no volume + return getMinX() == getMaxX() || getMinY() == getMaxY() || getMinZ() == getMaxZ(); + } + + default boolean sameAs(Box other) { + return getMinX() == other.getMinX() && getMinY() == other.getMinY() && getMinZ() == other.getMinZ() && getMaxX() == other.getMaxX() && getMaxY() == other.getMaxY() && getMaxZ() == other.getMaxZ(); + } + + default boolean sameAs(Box other, int margin) { + return getMinX() == other.getMinX() - margin && + getMinY() == other.getMinY() - margin && + getMinZ() == other.getMinZ() - margin && + getMaxX() == other.getMaxX() + margin && + getMaxY() == other.getMaxY() + margin && + getMaxZ() == other.getMaxZ() + margin; + } + + default boolean sameAs(AABB other) { + return getMinX() == Math.floor(other.minX) + && getMinY() == Math.floor(other.minY) + && getMinZ() == Math.floor(other.minZ) + && getMaxX() == Math.ceil(other.maxX) + && getMaxY() == Math.ceil(other.maxY) + && getMaxZ() == Math.ceil(other.maxZ); + } + + default boolean intersects(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + return this.getMinX() < maxX && this.getMaxX() > minX && this.getMinY() < maxY && this.getMaxY() > minY && this.getMinZ() < maxZ && this.getMaxZ() > minZ; + } + + default boolean intersects(Box other) { + return this.intersects(other.getMinX(), other.getMinY(), other.getMinZ(), other.getMaxX(), other.getMaxY(), other.getMaxZ()); + } + + default boolean contains(int x, int y, int z) { + return x >= getMinX() + && x <= getMaxX() + && y >= getMinY() + && y <= getMaxY() + && z >= getMinZ() + && z <= getMaxZ(); + } + + default boolean contains(Box other) { + return other.getMinX() >= this.getMinX() + && other.getMaxX() <= this.getMaxX() + && other.getMinY() >= this.getMinY() + && other.getMaxY() <= this.getMaxY() + && other.getMinZ() >= this.getMinZ() + && other.getMaxZ() <= this.getMaxZ(); + } + + default void forEachContained(CoordinateConsumer func) { + int minX = getMinX(); + int minY = getMinY(); + int minZ = getMinZ(); + int maxX = getMaxX(); + int maxY = getMaxY(); + int maxZ = getMaxZ(); + + for (int x = minX; x < maxX; x++) { + for (int y = minY; y < maxY; y++) { + for (int z = minZ; z < maxZ; z++) { + func.accept(x, y, z); + } + } + } + } + + default boolean hasPowerOf2Sides() { + // this is only true if all individual side lengths are powers of 2 + return Mth.isPowerOfTwo(volume()); + } + + default MutableBox union(Box other) { + int minX = Math.min(this.getMinX(), other.getMinX()); + int minY = Math.min(this.getMinY(), other.getMinY()); + int minZ = Math.min(this.getMinZ(), other.getMinZ()); + int maxX = Math.max(this.getMaxX(), other.getMaxX()); + int maxY = Math.max(this.getMaxY(), other.getMaxY()); + int maxZ = Math.max(this.getMaxZ(), other.getMaxZ()); + return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ); + } + + default MutableBox intersect(Box other) { + int minX = Math.max(this.getMinX(), other.getMinX()); + int minY = Math.max(this.getMinY(), other.getMinY()); + int minZ = Math.max(this.getMinZ(), other.getMinZ()); + int maxX = Math.min(this.getMaxX(), other.getMaxX()); + int maxY = Math.min(this.getMaxY(), other.getMaxY()); + int maxZ = Math.min(this.getMaxZ(), other.getMaxZ()); + return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ); + } + + default AABB toAABB() { + return new AABB(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ()); + } + + default MutableBox copy() { + return new MutableBox(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ()); + } + + @FunctionalInterface + interface CoordinateConsumer { + void accept(int x, int y, int z); + } +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/flywheel/box/MutableBox.java b/src/main/java/com/simibubi/create/foundation/utility/flywheel/box/MutableBox.java new file mode 100644 index 000000000..85d77f9d0 --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/flywheel/box/MutableBox.java @@ -0,0 +1,329 @@ +package com.simibubi.create.foundation.utility.flywheel.box; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.SectionPos; +import net.minecraft.core.Vec3i; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.AABB; + +import java.util.Collection; + +public class MutableBox implements Box { + protected int minX; + protected int minY; + protected int minZ; + protected int maxX; + protected int maxY; + protected int maxZ; + + public MutableBox() { + } + + public MutableBox(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) { + this.minX = minX; + this.minY = minY; + this.minZ = minZ; + this.maxX = maxX; + this.maxY = maxY; + this.maxZ = maxZ; + } + + public static MutableBox from(AABB aabb) { + int minX = (int) Math.floor(aabb.minX); + int minY = (int) Math.floor(aabb.minY); + int minZ = (int) Math.floor(aabb.minZ); + int maxX = (int) Math.ceil(aabb.maxX); + int maxY = (int) Math.ceil(aabb.maxY); + int maxZ = (int) Math.ceil(aabb.maxZ); + return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ); + } + + public static MutableBox from(Vec3i pos) { + return new MutableBox(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); + } + + public static MutableBox from(SectionPos pos) { + return new MutableBox(pos.minBlockX(), pos.minBlockY(), pos.minBlockZ(), pos.maxBlockX() + 1, pos.maxBlockY() + 1, pos.maxBlockZ() + 1); + } + + public static MutableBox from(Vec3i start, Vec3i end) { + return new MutableBox(start.getX(), start.getY(), start.getZ(), end.getX() + 1, end.getY() + 1, end.getZ() + 1); + } + + public static MutableBox ofRadius(int radius) { + return new MutableBox(-radius, -radius, -radius, radius + 1, radius + 1, radius + 1); + } + + public static Box containingAll(Collection positions) { + if (positions.isEmpty()) { + return new MutableBox(); + } + int minX = Integer.MAX_VALUE; + int minY = Integer.MAX_VALUE; + int minZ = Integer.MAX_VALUE; + int maxX = Integer.MIN_VALUE; + int maxY = Integer.MIN_VALUE; + int maxZ = Integer.MIN_VALUE; + for (BlockPos pos : positions) { + minX = Math.min(minX, pos.getX()); + minY = Math.min(minY, pos.getY()); + minZ = Math.min(minZ, pos.getZ()); + maxX = Math.max(maxX, pos.getX()); + maxY = Math.max(maxY, pos.getY()); + maxZ = Math.max(maxZ, pos.getZ()); + } + return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ); + } + + @Override + public int getMinX() { + return minX; + } + + @Override + public int getMinY() { + return minY; + } + + @Override + public int getMinZ() { + return minZ; + } + + @Override + public int getMaxX() { + return maxX; + } + + @Override + public int getMaxY() { + return maxY; + } + + @Override + public int getMaxZ() { + return maxZ; + } + + public void setMinX(int minX) { + this.minX = minX; + } + + public void setMinY(int minY) { + this.minY = minY; + } + + public MutableBox setMinZ(int minZ) { + this.minZ = minZ; + return this; + } + + public void setMaxX(int maxX) { + this.maxX = maxX; + } + + public void setMaxY(int maxY) { + this.maxY = maxY; + } + + public void setMaxZ(int maxZ) { + this.maxZ = maxZ; + } + + public void setMin(int x, int y, int z) { + minX = x; + minY = y; + minZ = z; + } + + public void setMax(int x, int y, int z) { + maxX = x; + maxY = y; + maxZ = z; + } + + public void setMin(Vec3i v) { + setMin(v.getX(), v.getY(), v.getZ()); + } + + public void setMax(Vec3i v) { + setMax(v.getX(), v.getY(), v.getZ()); + } + + public void assign(Box other) { + minX = other.getMinX(); + minY = other.getMinY(); + minZ = other.getMinZ(); + maxX = other.getMaxX(); + maxY = other.getMaxY(); + maxZ = other.getMaxZ(); + } + + public void assign(AABB other) { + minX = (int) Math.floor(other.minX); + minY = (int) Math.floor(other.minY); + minZ = (int) Math.floor(other.minZ); + maxX = (int) Math.ceil(other.maxX); + maxY = (int) Math.ceil(other.maxY); + maxZ = (int) Math.ceil(other.maxZ); + } + + public void assign(Vec3i start, Vec3i end) { + minX = start.getX(); + minY = start.getY(); + minZ = start.getZ(); + maxX = end.getX() + 1; + maxY = end.getY() + 1; + maxZ = end.getZ() + 1; + } + + public void unionAssign(Box other) { + minX = Math.min(this.minX, other.getMinX()); + minY = Math.min(this.minY, other.getMinY()); + minZ = Math.min(this.minZ, other.getMinZ()); + maxX = Math.max(this.maxX, other.getMaxX()); + maxY = Math.max(this.maxY, other.getMaxY()); + maxZ = Math.max(this.maxZ, other.getMaxZ()); + } + + public void unionAssign(AABB other) { + minX = Math.min(this.minX, (int) Math.floor(other.minX)); + minY = Math.min(this.minY, (int) Math.floor(other.minY)); + minZ = Math.min(this.minZ, (int) Math.floor(other.minZ)); + maxX = Math.max(this.maxX, (int) Math.ceil(other.maxX)); + maxY = Math.max(this.maxY, (int) Math.ceil(other.maxY)); + maxZ = Math.max(this.maxZ, (int) Math.ceil(other.maxZ)); + } + + public void intersectAssign(Box other) { + minX = Math.max(this.minX, other.getMinX()); + minY = Math.max(this.minY, other.getMinY()); + minZ = Math.max(this.minZ, other.getMinZ()); + maxX = Math.min(this.maxX, other.getMaxX()); + maxY = Math.min(this.maxY, other.getMaxY()); + maxZ = Math.min(this.maxZ, other.getMaxZ()); + } + + public void fixMinMax() { + int minX = Math.min(this.minX, this.maxX); + int minY = Math.min(this.minY, this.maxY); + int minZ = Math.min(this.minZ, this.maxZ); + int maxX = Math.max(this.minX, this.maxX); + int maxY = Math.max(this.minY, this.maxY); + int maxZ = Math.max(this.minZ, this.maxZ); + + this.minX = minX; + this.minY = minY; + this.minZ = minZ; + this.maxX = maxX; + this.maxY = maxY; + this.maxZ = maxZ; + } + + public void translate(int x, int y, int z) { + minX = minX + x; + maxX = maxX + x; + minY = minY + y; + maxY = maxY + y; + minZ = minZ + z; + maxZ = maxZ + z; + } + + public void translate(Vec3i by) { + translate(by.getX(), by.getY(), by.getZ()); + } + + public void grow(int x, int y, int z) { + minX = minX - x; + minY = minY - y; + minZ = minZ - z; + maxX = maxX + x; + maxY = maxY + y; + maxZ = maxZ + z; + } + + public void grow(int s) { + this.grow(s, s, s); + } + + /** + * Grow this box to have power of 2 side lengths, scaling from the minimum coords. + */ + public void nextPowerOf2() { + int sizeX = Mth.smallestEncompassingPowerOfTwo(sizeX()); + int sizeY = Mth.smallestEncompassingPowerOfTwo(sizeY()); + int sizeZ = Mth.smallestEncompassingPowerOfTwo(sizeZ()); + + maxX = minX + sizeX; + maxY = minY + sizeY; + maxZ = minZ + sizeZ; + } + + /** + * Grow this box to have power of 2 side length, scaling from the center. + */ + public void nextPowerOf2Centered() { + int sizeX = sizeX(); + int sizeY = sizeY(); + int sizeZ = sizeZ(); + + int newSizeX = Mth.smallestEncompassingPowerOfTwo(sizeX); + int newSizeY = Mth.smallestEncompassingPowerOfTwo(sizeY); + int newSizeZ = Mth.smallestEncompassingPowerOfTwo(sizeZ); + + int diffX = newSizeX - sizeX; + int diffY = newSizeY - sizeY; + int diffZ = newSizeZ - sizeZ; + + minX = minX - diffX / 2; // floor division for the minimums + minY = minY - diffY / 2; + minZ = minZ - diffZ / 2; + maxX = maxX + (diffX + 1) / 2; // ceiling divison for the maximums + maxY = maxY + (diffY + 1) / 2; + maxZ = maxZ + (diffZ + 1) / 2; + } + + public void mirrorAbout(Direction.Axis axis) { + Vec3i axisVec = Direction.get(Direction.AxisDirection.POSITIVE, axis) + .getNormal(); + int flipX = axisVec.getX() - 1; + int flipY = axisVec.getY() - 1; + int flipZ = axisVec.getZ() - 1; + + int maxX = this.maxX * flipX; + int maxY = this.maxY * flipY; + int maxZ = this.maxZ * flipZ; + this.maxX = this.minX * flipX; + this.maxY = this.minY * flipY; + this.maxZ = this.minZ * flipZ; + this.minX = maxX; + this.minY = maxY; + this.minZ = maxZ; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null) return false; + if (!(o instanceof Box that)) return false; + + return this.sameAs(that); + } + + @Override + public int hashCode() { + int result = minX; + result = 31 * result + minY; + result = 31 * result + minZ; + result = 31 * result + maxX; + result = 31 * result + maxY; + result = 31 * result + maxZ; + return result; + } + + @Override + public String toString() { + return "(" + minX + ", " + minY + ", " + minZ + ")->(" + maxX + ", " + maxY + ", " + maxZ + ')'; + } +} diff --git a/src/main/java/com/simibubi/create/foundation/utility/flywheel/light/LightVolume.java b/src/main/java/com/simibubi/create/foundation/utility/flywheel/light/LightVolume.java new file mode 100644 index 000000000..2da7cacef --- /dev/null +++ b/src/main/java/com/simibubi/create/foundation/utility/flywheel/light/LightVolume.java @@ -0,0 +1,219 @@ +package com.simibubi.create.foundation.utility.flywheel.light; + +import com.simibubi.create.foundation.utility.flywheel.box.Box; +import com.simibubi.create.foundation.utility.flywheel.box.MutableBox; + +import dev.engine_room.flywheel.lib.memory.MemoryBlock; +import net.minecraft.core.BlockPos; +import net.minecraft.core.SectionPos; +import net.minecraft.world.level.BlockAndTintGetter; + +import net.minecraft.world.level.LightLayer; + +import org.lwjgl.system.MemoryUtil; + +public class LightVolume implements Box { + protected final BlockAndTintGetter level; + protected final MutableBox box = new MutableBox(); + protected MemoryBlock lightData; + + public LightVolume(BlockAndTintGetter level, Box sampleVolume) { + this.level = level; + this.setBox(sampleVolume); + + this.lightData = MemoryBlock.malloc(this.box.volume() * 2); + } + + public Box getVolume() { + return box; + } + + @Override + public int getMinX() { + return box.getMinX(); + } + + @Override + public int getMinY() { + return box.getMinY(); + } + + @Override + public int getMinZ() { + return box.getMinZ(); + } + + @Override + public int getMaxX() { + return box.getMaxX(); + } + + @Override + public int getMaxY() { + return box.getMaxY(); + } + + @Override + public int getMaxZ() { + return box.getMaxZ(); + } + + public boolean isInvalid() { + return lightData == null; + } + + protected void setBox(Box box) { + this.box.assign(box); + } + + public short getPackedLight(int x, int y, int z) { + if (box.contains(x, y, z)) { + return MemoryUtil.memGetShort(levelPosToPtr(x, y, z)); + } else { + return 0; + } + } + + public void move(Box newSampleVolume) { + if (lightData == null) return; + + setBox(newSampleVolume); + int neededCapacity = box.volume() * 2; + if (neededCapacity > lightData.size()) { + lightData = lightData.realloc(neededCapacity); + } + initialize(); + } + + /** + * Completely (re)populate this volume with block and sky lighting data. + * This is expensive and should be avoided. + */ + public void initialize() { + if (lightData == null) return; + + copyLight(getVolume()); + markDirty(); + } + + protected void markDirty() { + // noop + } + + public void delete() { + lightData.free(); + lightData = null; + } + + /** + * Copy all light from the level into this volume. + * + * @param levelVolume the region in the level to copy data from. + */ + public void copyLight(Box levelVolume) { + BlockPos.MutableBlockPos pos = new BlockPos.MutableBlockPos(); + + int xShift = box.getMinX(); + int yShift = box.getMinY(); + int zShift = box.getMinZ(); + + levelVolume.forEachContained((x, y, z) -> { + pos.set(x, y, z); + + int block = this.level.getBrightness(LightLayer.BLOCK, pos); + int sky = this.level.getBrightness(LightLayer.SKY, pos); + + writeLight(x - xShift, y - yShift, z - zShift, block, sky); + }); + } + + protected void writeLight(int x, int y, int z, int block, int sky) { + byte b = (byte) ((block & 0xF) << 4); + byte s = (byte) ((sky & 0xF) << 4); + + long ptr = boxPosToPtr(x, y, z); + MemoryUtil.memPutByte(ptr, b); + MemoryUtil.memPutByte(ptr + 1, s); + } + + /** + * Copy block light from the level into this volume. + * + * @param levelVolume the region in the level to copy data from. + */ + public void copyBlock(Box levelVolume) { + var pos = new BlockPos.MutableBlockPos(); + + int xShift = box.getMinX(); + int yShift = box.getMinY(); + int zShift = box.getMinZ(); + + levelVolume.forEachContained((x, y, z) -> { + int light = this.level.getBrightness(LightLayer.BLOCK, pos.set(x, y, z)); + + writeBlock(x - xShift, y - yShift, z - zShift, light); + }); + } + + protected void writeBlock(int x, int y, int z, int block) { + byte b = (byte) ((block & 0xF) << 4); + + MemoryUtil.memPutByte(boxPosToPtr(x, y, z), b); + } + + /** + * Copy sky light from the level into this volume. + * + * @param levelVolume the region in the level to copy data from. + */ + public void copySky(Box levelVolume) { + var pos = new BlockPos.MutableBlockPos(); + + int xShift = box.getMinX(); + int yShift = box.getMinY(); + int zShift = box.getMinZ(); + + levelVolume.forEachContained((x, y, z) -> { + int light = this.level.getBrightness(LightLayer.SKY, pos.set(x, y, z)); + + writeSky(x - xShift, y - yShift, z - zShift, light); + }); + } + + protected void writeSky(int x, int y, int z, int sky) { + byte s = (byte) ((sky & 0xF) << 4); + + MemoryUtil.memPutByte(boxPosToPtr(x, y, z) + 1, s); + } + + protected long levelPosToPtr(int x, int y, int z) { + return lightData.ptr() + levelPosToPtrOffset(x, y, z); + } + + protected long boxPosToPtr(int x, int y, int z) { + return lightData.ptr() + boxPosToPtrOffset(x, y, z); + } + + protected int levelPosToPtrOffset(int x, int y, int z) { + x -= box.getMinX(); + y -= box.getMinY(); + z -= box.getMinZ(); + return boxPosToPtrOffset(x, y, z); + } + + protected int boxPosToPtrOffset(int x, int y, int z) { + return (x + box.sizeX() * (y + z * box.sizeY())) * 2; + } + + public void onLightUpdate(LightLayer type, SectionPos pos) { + if (lightData == null) return; + + MutableBox vol = MutableBox.from(pos); + if (!vol.intersects(getVolume())) return; + vol.intersectAssign(getVolume()); // compute the region contained by us that has dirty lighting data. + + if (type == LightLayer.BLOCK) copyBlock(vol); + else if (type == LightLayer.SKY) copySky(vol); + markDirty(); + } +}