diff --git a/gradle.properties b/gradle.properties index 3063a0283..923699fb4 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-136 +flywheel_version = 1.0.0-beta-145 jei_minecraft_version = 1.20.1 jei_version = 15.10.0.39 curios_minecraft_version = 1.20.1 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 d5dd84a90..df9a1a158 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 @@ -5,17 +5,16 @@ import java.util.function.Consumer; import com.mojang.math.Axis; import com.simibubi.create.content.kinetics.base.KineticBlockEntity; import com.simibubi.create.content.kinetics.base.ShaftVisual; -import com.simibubi.create.foundation.render.ConditionalInstance; -import com.simibubi.create.foundation.render.GroupInstance; -import com.simibubi.create.foundation.render.SelectInstance; 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.instance.OrientedInstance; +import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.math.MoreMath; import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual; +import dev.engine_room.flywheel.lib.visual.util.SmartRecycler; import it.unimi.dsi.fastutil.bytes.ByteArrayList; import it.unimi.dsi.fastutil.bytes.ByteList; import it.unimi.dsi.fastutil.longs.LongOpenHashSet; @@ -29,9 +28,8 @@ import net.minecraft.world.level.LightLayer; public abstract class AbstractPulleyVisual extends ShaftVisual implements SimpleDynamicVisual { private final OrientedInstance coil; - private final SelectInstance magnet; - private final GroupInstance rope; - private final ConditionalInstance halfRope; + private final TransformedInstance magnet; + private final SmartRecycler rope; protected final Direction rotatingAbout; protected final Axis rotationAxis; @@ -50,14 +48,12 @@ public abstract class AbstractPulleyVisual extends .position(getVisualPosition()); coil.setChanged(); - magnet = new SelectInstance<>(this::getMagnetModelIndex); - magnet.addModel(getMagnetModel()) - .addModel(getHalfMagnetModel()); + magnet = magnetInstancer().createInstance(); - rope = new GroupInstance<>(getRopeModel()); - halfRope = new ConditionalInstance<>(getHalfRopeModel()).withCondition(this::shouldRenderHalfRope); + rope = new SmartRecycler<>(b -> b ? getHalfRopeModel().createInstance() : getRopeModel().createInstance()); updateOffset(partialTick); + updateLight(partialTick); } @Override @@ -66,67 +62,68 @@ public abstract class AbstractPulleyVisual extends lightCache.updateSections(); } - protected abstract Instancer getRopeModel(); + protected abstract Instancer getRopeModel(); - protected abstract Instancer getMagnetModel(); + protected abstract Instancer getMagnetModel(); - protected abstract Instancer getHalfMagnetModel(); + protected abstract Instancer getHalfMagnetModel(); protected abstract Instancer getCoilModel(); - protected abstract Instancer getHalfRopeModel(); + protected abstract Instancer getHalfRopeModel(); protected abstract float getOffset(float pt); protected abstract boolean isRunning(); + private Instancer magnetInstancer() { + return offset > .25f ? getMagnetModel() : getHalfMagnetModel(); + } + @Override public void beginFrame(DynamicVisual.Context ctx) { updateOffset(ctx.partialTick()); coil.rotation(rotationAxis.rotationDegrees(offset * 180)) .setChanged(); - int neededRopeCount = getNeededRopeCount(); - rope.resize(neededRopeCount); + magnet.setVisible(isRunning() || offset == 0); - magnet.update() - .get() - .ifPresent(data -> { - int i = Math.max(0, Mth.floor(offset)); - int light = lightCache.getPackedLight(i); - data.position(getVisualPosition()) - .translatePosition(0, -offset, 0) - .light(light) - .setChanged(); - }); + magnetInstancer().stealInstance(magnet); - halfRope.update() - .get() - .ifPresent(rope1 -> { - float f = offset % 1; - float halfRopeNudge = f > .75f ? f - 1 : f; + magnet.setIdentityTransform() + .translate(getVisualPosition()) + .translate(0, -offset, 0) + .light(lightCache.getPackedLight(Math.max(0, Mth.floor(offset)))) + .setChanged(); - int light = lightCache.getPackedLight(0); - rope1.position(getVisualPosition()) - .translatePosition(0, -halfRopeNudge, 0) - .light(light) - .setChanged(); - }); + rope.resetCount(); + + if (shouldRenderHalfRope()) { + float f = offset % 1; + float halfRopeNudge = f > .75f ? f - 1 : f; + + rope.get(true).setIdentityTransform() + .translate(getVisualPosition()) + .translate(0, -halfRopeNudge, 0) + .light(lightCache.getPackedLight(0)) + .setChanged(); + } if (isRunning()) { - int size = rope.size(); - for (int i = 0; i < size; i++) { - int light = lightCache.getPackedLight(size - 1 - i); + int neededRopeCount = getNeededRopeCount(); - rope.get(i) - .position(getVisualPosition()) - .translatePosition(0, -offset + i + 1, 0) - .light(light) + for (int i = 0; i < neededRopeCount; i++) { + + rope.get(false) + .setIdentityTransform() + .translate(getVisualPosition()) + .translate(0, -offset + i + 1, 0) + .light(lightCache.getPackedLight(neededRopeCount - 1 - i)) .setChanged(); } - } else { - rope.clear(); } + + rope.discardExtra(); } @Override @@ -151,21 +148,11 @@ public abstract class AbstractPulleyVisual extends return offset > .75f && (f < .25f || f > .75f); } - private int getMagnetModelIndex() { - if (isRunning() || offset == 0) { - return offset > .25f ? 0 : 1; - } else { - return -1; - } - } - @Override public void collectCrumblingInstances(Consumer consumer) { super.collectCrumblingInstances(consumer); consumer.accept(coil); - magnet.forEach(consumer); - rope.forEach(consumer); - halfRope.forEach(consumer); + consumer.accept(magnet); } @Override @@ -173,8 +160,7 @@ public abstract class AbstractPulleyVisual extends super._delete(); coil.delete(); magnet.delete(); - rope.clear(); - halfRope.delete(); + rope.delete(); } private class LightCache { @@ -186,6 +172,7 @@ public abstract class AbstractPulleyVisual extends public void setSize(int size) { if (size != data.size()) { data.size(size); + update(); int sectionCount = MoreMath.ceilingDiv(size + 15 - pos.getY() + pos.getY() / 4 * 4, SectionPos.SECTION_SIZE); if (sectionCount != this.sectionCount) { @@ -215,7 +202,7 @@ public abstract class AbstractPulleyVisual extends for (int i = 0; i < data.size(); i++) { int blockLight = level.getBrightness(LightLayer.BLOCK, mutablePos); int skyLight = level.getBrightness(LightLayer.SKY, mutablePos); - int light = ((skyLight << 4) & 0xF) | (blockLight & 0xF); + int light = ((skyLight & 0xF) << 4) | (blockLight & 0xF); data.set(i, (byte) light); mutablePos.move(Direction.DOWN); } 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 d530c063f..417541ca9 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 @@ -7,6 +7,7 @@ import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.InstanceTypes; import dev.engine_room.flywheel.lib.instance.OrientedInstance; +import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.model.Models; public class HosePulleyVisual extends AbstractPulleyVisual { @@ -15,18 +16,18 @@ public class HosePulleyVisual extends AbstractPulleyVisual getRopeModel() { - return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE)); + protected Instancer getRopeModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE)); } @Override - protected Instancer getMagnetModel() { - return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_MAGNET)); + protected Instancer getMagnetModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_MAGNET)); } @Override - protected Instancer getHalfMagnetModel() { - return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_HALF_MAGNET)); + protected Instancer getHalfMagnetModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_HALF_MAGNET)); } @Override @@ -35,8 +36,8 @@ public class HosePulleyVisual extends AbstractPulleyVisual getHalfRopeModel() { - return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.HOSE_HALF)); + protected Instancer getHalfRopeModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.HOSE_HALF)); } @Override 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 ce9d0da49..3930f79e3 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 @@ -9,6 +9,7 @@ import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.lib.instance.InstanceTypes; import dev.engine_room.flywheel.lib.instance.OrientedInstance; +import dev.engine_room.flywheel.lib.instance.TransformedInstance; import dev.engine_room.flywheel.lib.model.Models; public class RopePulleyVisual extends AbstractPulleyVisual { @@ -17,18 +18,18 @@ public class RopePulleyVisual extends AbstractPulleyVisual { } @Override - protected Instancer getRopeModel() { - return instancerProvider().instancer(InstanceTypes.ORIENTED, VirtualRenderHelper.blockModel(AllBlocks.ROPE.getDefaultState())); + protected Instancer getRopeModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.ROPE.getDefaultState())); } @Override - protected Instancer getMagnetModel() { - return instancerProvider().instancer(InstanceTypes.ORIENTED, VirtualRenderHelper.blockModel(AllBlocks.PULLEY_MAGNET.getDefaultState())); + protected Instancer getMagnetModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, VirtualRenderHelper.blockModel(AllBlocks.PULLEY_MAGNET.getDefaultState())); } @Override - protected Instancer getHalfMagnetModel() { - return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_HALF_MAGNET)); + protected Instancer getHalfMagnetModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ROPE_HALF_MAGNET)); } @Override @@ -37,8 +38,8 @@ public class RopePulleyVisual extends AbstractPulleyVisual { } @Override - protected Instancer getHalfRopeModel() { - return instancerProvider().instancer(InstanceTypes.ORIENTED, Models.partial(AllPartialModels.ROPE_HALF)); + protected Instancer getHalfRopeModel() { + return instancerProvider().instancer(InstanceTypes.TRANSFORMED, Models.partial(AllPartialModels.ROPE_HALF)); } @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 7d1b430bb..bda99f70a 100644 --- a/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java +++ b/src/main/java/com/simibubi/create/foundation/render/AllInstanceTypes.java @@ -49,7 +49,7 @@ public class AllInstanceTypes { MemoryUtil.memPutByte(ptr + 33, instance.rotationAxisY); MemoryUtil.memPutByte(ptr + 34, instance.rotationAxisZ); }) - .register(); + .build(); public static final InstanceType BELT = SimpleInstanceType.builder(BeltInstance::new) .cullShader(asResource("instance/cull/belt.glsl")) @@ -87,7 +87,7 @@ public class AllInstanceTypes { MemoryUtil.memPutFloat(ptr + 68, instance.maxV); MemoryUtil.memPutFloat(ptr + 72, instance.scrollMult); }) - .register(); + .build(); // TODO: use this for belts too public static final InstanceType SCROLLING = SimpleInstanceType.builder(ScrollInstance::new) @@ -121,7 +121,7 @@ public class AllInstanceTypes { MemoryUtil.memPutFloat(ptr + 56, instance.scaleU); MemoryUtil.memPutFloat(ptr + 60, instance.scaleV); }) - .register(); + .build(); public static final InstanceType ACTOR = SimpleInstanceType.builder(ActorInstance::new) .cullShader(asResource("instance/cull/actor.glsl")) @@ -151,7 +151,7 @@ public class AllInstanceTypes { MemoryUtil.memPutByte(ptr + 42, instance.rotationCenterZ); MemoryUtil.memPutFloat(ptr + 44, instance.speed); }) - .register(); + .build(); // TODO: remove public static final InstanceType FLAP = SimpleInstanceType.builder(FlapInstance::new) @@ -183,7 +183,7 @@ public class AllInstanceTypes { MemoryUtil.memPutFloat(ptr + 48, instance.flapScale); MemoryUtil.memPutFloat(ptr + 52, instance.flapness); }) - .register(); + .build(); public static void init() { // noop diff --git a/src/main/java/com/simibubi/create/foundation/render/ConditionalInstance.java b/src/main/java/com/simibubi/create/foundation/render/ConditionalInstance.java deleted file mode 100644 index c8c44b4c1..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/ConditionalInstance.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.simibubi.create.foundation.render; - -import java.util.Optional; -import java.util.function.Consumer; - -import javax.annotation.Nullable; - -import dev.engine_room.flywheel.api.instance.Instance; -import dev.engine_room.flywheel.api.instance.Instancer; -import dev.engine_room.flywheel.lib.instance.AbstractInstance; - -public class ConditionalInstance { - - final Instancer model; - ICondition condition; - - Consumer setupFunc; - - @Nullable - private D instance; - - public ConditionalInstance(Instancer model) { - this.model = model; - this.condition = () -> true; - } - - public ConditionalInstance withSetupFunc(Consumer setupFunc) { - this.setupFunc = setupFunc; - return this; - } - - public ConditionalInstance withCondition(ICondition condition) { - this.condition = condition; - return this; - } - - public ConditionalInstance update() { - boolean shouldShow = condition.shouldShow(); - if (shouldShow && instance == null) { - instance = model.createInstance(); - if (setupFunc != null) setupFunc.accept(instance); - } 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(); - } - - public void forEach(Consumer consumer) { - if (instance != null) { - consumer.accept(instance); - } - } - - @FunctionalInterface - public interface ICondition { - boolean shouldShow(); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/GroupInstance.java b/src/main/java/com/simibubi/create/foundation/render/GroupInstance.java deleted file mode 100644 index 00255bd77..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/GroupInstance.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.simibubi.create.foundation.render; - -import java.util.AbstractCollection; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import dev.engine_room.flywheel.api.instance.Instancer; -import dev.engine_room.flywheel.lib.instance.AbstractInstance; - -public class GroupInstance extends AbstractCollection { - - final Instancer model; - final List backing; - - public GroupInstance(Instancer model) { - this.model = model; - - this.backing = new ArrayList<>(); - } - - public GroupInstance(Instancer 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(AbstractInstance::delete); - unnecessary.clear(); - } - - return true; - } - - public D 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(AbstractInstance::delete); - backing.clear(); - } -} diff --git a/src/main/java/com/simibubi/create/foundation/render/SelectInstance.java b/src/main/java/com/simibubi/create/foundation/render/SelectInstance.java deleted file mode 100644 index f638146d8..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/SelectInstance.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.simibubi.create.foundation.render; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.function.Consumer; - -import javax.annotation.Nullable; - -import dev.engine_room.flywheel.api.instance.Instance; -import dev.engine_room.flywheel.api.instance.Instancer; - -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(Instancer model) { - models.add(model); - return this; - } - - public SelectInstance update() { - int i = selector.modelIndexToShow(); - - if (i < 0 || i >= models.size()) { - if (current != null) { - current.handle().setDeleted(); - current = null; - } - } else if (i != last) { - if (current != null) current.handle().setDeleted(); - - current = models.get(i) - .createInstance(); - } - - last = i; - return this; - } - - public Optional get() { - return Optional.ofNullable(current); - } - - public void delete() { - if (current != null) current.handle().setDeleted(); - } - - public void forEach(Consumer consumer) { - if (current != null) { - consumer.accept(current); - } - } - - public interface ModelSelector { - int modelIndexToShow(); - } -}