diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 6393c5701..36fc3fec0 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -31,5 +31,6 @@ gradlePlugin { } dependencies { - implementation("dev.architectury.loom:dev.architectury.loom.gradle.plugin:1.6-SNAPSHOT") + // FIXME: This should not hard-code the Loom version. + implementation("dev.architectury.loom:dev.architectury.loom.gradle.plugin:1.6.397") } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/vertex/VertexList.java b/common/src/api/java/dev/engine_room/flywheel/api/vertex/VertexList.java index 975f653fe..c45832200 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/vertex/VertexList.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/vertex/VertexList.java @@ -1,8 +1,5 @@ package dev.engine_room.flywheel.api.vertex; -import org.joml.Vector3f; -import org.joml.Vector4f; - /** * A read only view of a vertex buffer. * @@ -40,14 +37,6 @@ public interface VertexList { float normalZ(int index); - default Vector4f getPos(int i, Vector4f dest) { - return dest.set(x(i), y(i), z(i)); - } - - default Vector3f getNormal(int i, Vector3f dest) { - return dest.set(normalX(i), normalY(i), normalZ(i)); - } - default void write(MutableVertexList dst, int srcIndex, int dstIndex) { dst.x(dstIndex, x(srcIndex)); dst.y(dstIndex, y(srcIndex)); diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visual/Effect.java b/common/src/api/java/dev/engine_room/flywheel/api/visual/Effect.java index 1b7e233e6..d3ed43cf2 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visual/Effect.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visual/Effect.java @@ -1,5 +1,7 @@ package dev.engine_room.flywheel.api.visual; +import java.util.List; + import dev.engine_room.flywheel.api.visualization.VisualizationContext; /** @@ -14,5 +16,5 @@ public interface Effect { * @param ctx The visualization context. * @return An arbitrary EffectVisual. */ - EffectVisual visualize(VisualizationContext ctx); + List> visualize(VisualizationContext ctx, float partialTick); } diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visual/LitVisual.java b/common/src/api/java/dev/engine_room/flywheel/api/visual/LitVisual.java index e5d983eb5..4f05e7687 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visual/LitVisual.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visual/LitVisual.java @@ -13,16 +13,14 @@ */ public interface LitVisual extends Visual { /** - * Called when a section this visual is contained in receives a light update. + * Set the notifier object. * - *

Even if multiple sections are updated at the same time, this method will only be called once.

+ *

This method is only called once right after the visual + * is created and before {@link #collectLightSections}.

* - *

The implementation is free to parallelize calls to this method, as well as execute the plan - * returned by {@link DynamicVisual#planFrame} simultaneously. It is safe to query/update light here, - * but you must ensure proper synchronization if you want to mutate anything outside this visual or - * anything that is also mutated within {@link DynamicVisual#planFrame}.

+ * @param notifier The notifier. */ - void updateLight(); + void setLightSectionNotifier(Notifier notifier); /** * Collect the sections that this visual is contained in. @@ -36,14 +34,18 @@ public interface LitVisual extends Visual { void collectLightSections(LongConsumer consumer); /** - * Set the notifier object. + * Called when a section this visual is contained in receives a light update. * - *

This method is only called once, upon visual creation, - * after {@link #init} and before {@link #collectLightSections}.

+ *

Even if multiple sections are updated at the same time, this method will only be called once.

* - * @param notifier The notifier. + *

The implementation is free to parallelize calls to this method, as well as execute the plan + * returned by {@link DynamicVisual#planFrame} simultaneously. It is safe to query/update light here, + * but you must ensure proper synchronization if you want to mutate anything outside this visual or + * anything that is also mutated within {@link DynamicVisual#planFrame}.

+ * + *

This method not is invoked automatically after visual creation.

*/ - void initLightSectionNotifier(Notifier notifier); + void updateLight(float partialTick); /** * A notifier object that can be used to indicate to the impl diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visual/Visual.java b/common/src/api/java/dev/engine_room/flywheel/api/visual/Visual.java index 7ecbe1cfd..4aed57f59 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visual/Visual.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visual/Visual.java @@ -8,13 +8,6 @@ * @see LitVisual */ public interface Visual { - /** - * Initialize instances here. - * - *

This method will be called exactly once upon visual creation.

- */ - void init(float partialTick); - /** * Update instances here. * diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visualization/BlockEntityVisualizer.java b/common/src/api/java/dev/engine_room/flywheel/api/visualization/BlockEntityVisualizer.java index f24fd1dc5..41b5f99e9 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visualization/BlockEntityVisualizer.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visualization/BlockEntityVisualizer.java @@ -1,5 +1,7 @@ package dev.engine_room.flywheel.api.visualization; +import java.util.List; + import dev.engine_room.flywheel.api.visual.BlockEntityVisual; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.world.level.block.entity.BlockEntity; @@ -16,7 +18,7 @@ public interface BlockEntityVisualizer { * @param blockEntity The block entity to construct a visual for. * @return The visual. */ - BlockEntityVisual createVisual(VisualizationContext ctx, T blockEntity); + List> createVisual(VisualizationContext ctx, T blockEntity, float partialTick); /** * Checks if the given block entity should not be rendered with the vanilla {@link BlockEntityRenderer}. diff --git a/common/src/api/java/dev/engine_room/flywheel/api/visualization/EntityVisualizer.java b/common/src/api/java/dev/engine_room/flywheel/api/visualization/EntityVisualizer.java index f7128f811..9e398da27 100644 --- a/common/src/api/java/dev/engine_room/flywheel/api/visualization/EntityVisualizer.java +++ b/common/src/api/java/dev/engine_room/flywheel/api/visualization/EntityVisualizer.java @@ -1,5 +1,7 @@ package dev.engine_room.flywheel.api.visualization; +import java.util.List; + import dev.engine_room.flywheel.api.visual.EntityVisual; import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.world.entity.Entity; @@ -16,7 +18,7 @@ public interface EntityVisualizer { * @param entity The entity to construct a visual for. * @return The visual. */ - EntityVisual createVisual(VisualizationContext ctx, T entity); + List> createVisual(VisualizationContext ctx, T entity, float partialTick); /** * Checks if the given entity should not render with the vanilla {@link EntityRenderer}. diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/AbstractInstancer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/AbstractInstancer.java index 3ab8d28e1..56fbfcf9d 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/AbstractInstancer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/AbstractInstancer.java @@ -8,7 +8,7 @@ import dev.engine_room.flywheel.api.instance.InstanceType; import dev.engine_room.flywheel.api.instance.Instancer; import dev.engine_room.flywheel.backend.engine.embed.Environment; -import dev.engine_room.flywheel.lib.util.AtomicBitset; +import dev.engine_room.flywheel.lib.util.AtomicBitSet; public abstract class AbstractInstancer implements Instancer { public final InstanceType type; @@ -19,8 +19,8 @@ public abstract class AbstractInstancer implements Instancer protected final ArrayList instances = new ArrayList<>(); protected final ArrayList handles = new ArrayList<>(); - protected final AtomicBitset changed = new AtomicBitset(); - protected final AtomicBitset deleted = new AtomicBitset(); + protected final AtomicBitSet changed = new AtomicBitSet(); + protected final AtomicBitSet deleted = new AtomicBitSet(); protected AbstractInstancer(InstanceType type, Environment environment) { this.type = type; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformWriter.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformWriter.java index 246d40edc..022cc8c8c 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformWriter.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/uniform/UniformWriter.java @@ -3,7 +3,7 @@ import org.joml.Matrix4f; import org.lwjgl.system.MemoryUtil; -import dev.engine_room.flywheel.lib.math.MatrixMath; +import dev.engine_room.flywheel.lib.util.ExtraMemoryOps; import net.minecraft.core.BlockPos; import net.minecraft.tags.FluidTags; import net.minecraft.world.level.Level; @@ -46,7 +46,7 @@ static long writeVec4(long ptr, float x, float y, float z, float w) { } static long writeMat4(long ptr, Matrix4f mat) { - MatrixMath.writeUnsafe(ptr, mat); + ExtraMemoryOps.putMatrix4f(ptr, mat); return ptr + 64; } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/ColoredLitInstance.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/ColoredLitInstance.java index a82ccf77d..ae0260965 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/ColoredLitInstance.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/ColoredLitInstance.java @@ -2,7 +2,6 @@ import dev.engine_room.flywheel.api.instance.InstanceHandle; import dev.engine_room.flywheel.api.instance.InstanceType; -import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.texture.OverlayTexture; public abstract class ColoredLitInstance extends AbstractInstance implements FlatLit { @@ -11,43 +10,42 @@ public abstract class ColoredLitInstance extends AbstractInstance implements Fla public byte b = (byte) 0xFF; public byte a = (byte) 0xFF; - public int packedLight; - public int overlay = OverlayTexture.NO_OVERLAY; + public int light = 0; public ColoredLitInstance(InstanceType type, InstanceHandle handle) { super(type, handle); } - public ColoredLitInstance setColor(int color) { - return setColor(color, false); + public ColoredLitInstance color(int color) { + return color(color, false); } - public ColoredLitInstance setColor(int color, boolean alpha) { + public ColoredLitInstance color(int color, boolean alpha) { byte r = (byte) ((color >> 16) & 0xFF); byte g = (byte) ((color >> 8) & 0xFF); byte b = (byte) (color & 0xFF); if (alpha) { byte a = (byte) ((color >> 24) & 0xFF); - return setColor(r, g, b, a); + return color(r, g, b, a); } else { - return setColor(r, g, b); + return color(r, g, b); } } - public ColoredLitInstance setColor(int r, int g, int b) { - return setColor((byte) r, (byte) g, (byte) b); + public ColoredLitInstance color(int r, int g, int b) { + return color((byte) r, (byte) g, (byte) b); } - public ColoredLitInstance setColor(byte r, byte g, byte b) { + public ColoredLitInstance color(byte r, byte g, byte b) { this.r = r; this.g = g; this.b = b; return this; } - public ColoredLitInstance setColor(byte r, byte g, byte b, byte a) { + public ColoredLitInstance color(byte r, byte g, byte b, byte a) { this.r = r; this.g = g; this.b = b; @@ -55,19 +53,14 @@ public ColoredLitInstance setColor(byte r, byte g, byte b, byte a) { return this; } - @Override - public ColoredLitInstance light(int blockLight, int skyLight) { - return light(LightTexture.pack(blockLight, skyLight)); - } - - @Override - public ColoredLitInstance light(int packedLight) { - this.packedLight = packedLight; + public ColoredLitInstance overlay(int overlay) { + this.overlay = overlay; return this; } - public ColoredLitInstance setOverlay(int overlay) { - this.overlay = overlay; + @Override + public ColoredLitInstance light(int light) { + this.light = light; return this; } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/FlatLit.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/FlatLit.java index 7a563706a..f9bb8a75e 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/FlatLit.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/FlatLit.java @@ -1,26 +1,64 @@ package dev.engine_room.flywheel.lib.instance; +import java.util.Iterator; +import java.util.stream.Stream; + +import org.jetbrains.annotations.Nullable; + import dev.engine_room.flywheel.api.instance.Instance; -import dev.engine_room.flywheel.lib.visual.AbstractVisual; +import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual; +import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual; import net.minecraft.client.renderer.LightTexture; /** - * An interface that implementors of {@link Instance} should also implement - * if they wish to make use of the relighting utilities in {@link AbstractVisual}. + * An interface that implementors of {@link Instance} should also implement if they wish to make use of + * {@link #relight} and the relighting utilities in {@link AbstractBlockEntityVisual} and {@link AbstractEntityVisual}. */ public interface FlatLit extends Instance { /** - * Set the block and sky light values for this instance. - * @param blockLight Block light value - * @param skyLight Sky light value + * Set the packed light value for this instance. + * @param packedLight Packed block and sky light per {@link LightTexture#pack(int, int)} * @return {@code this} for chaining */ - FlatLit light(int blockLight, int skyLight); + FlatLit light(int packedLight); /** - * Set the packed light value for this instance. - * @param packedLight Packed block and sky light per {@link LightTexture#pack(int, int)} + * Set the block and sky light values for this instance. + * @param blockLight Block light value + * @param skyLight Sky light value * @return {@code this} for chaining */ - FlatLit light(int packedLight); + default FlatLit light(int blockLight, int skyLight) { + return light(LightTexture.pack(blockLight, skyLight)); + } + + static void relight(int packedLight, @Nullable FlatLit... instances) { + for (FlatLit instance : instances) { + if (instance != null) { + instance.light(packedLight) + .handle() + .setChanged(); + } + } + } + + static void relight(int packedLight, Iterator<@Nullable FlatLit> instances) { + while (instances.hasNext()) { + FlatLit instance = instances.next(); + + if (instance != null) { + instance.light(packedLight) + .handle() + .setChanged(); + } + } + } + + static void relight(int packedLight, Iterable<@Nullable FlatLit> instances) { + relight(packedLight, instances.iterator()); + } + + static void relight(int packedLight, Stream<@Nullable FlatLit> instances) { + relight(packedLight, instances.iterator()); + } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java index fa1111641..0ab63f4b6 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/instance/InstanceTypes.java @@ -8,7 +8,7 @@ import dev.engine_room.flywheel.api.layout.FloatRepr; import dev.engine_room.flywheel.api.layout.IntegerRepr; import dev.engine_room.flywheel.api.layout.LayoutBuilder; -import dev.engine_room.flywheel.lib.math.MatrixMath; +import dev.engine_room.flywheel.lib.util.ExtraMemoryOps; public final class InstanceTypes { public static final InstanceType TRANSFORMED = SimpleInstanceType.builder(TransformedInstance::new) @@ -24,12 +24,10 @@ public final class InstanceTypes { MemoryUtil.memPutByte(ptr + 1, instance.g); MemoryUtil.memPutByte(ptr + 2, instance.b); MemoryUtil.memPutByte(ptr + 3, instance.a); - MemoryUtil.memPutShort(ptr + 4, (short) (instance.overlay & 0xFFFF)); - MemoryUtil.memPutShort(ptr + 6, (short) (instance.overlay >> 16 & 0xFFFF)); - MemoryUtil.memPutShort(ptr + 8, (short) (instance.packedLight & 0xFFFF)); - MemoryUtil.memPutShort(ptr + 10, (short) (instance.packedLight >> 16 & 0xFFFF)); - MatrixMath.writeUnsafe(ptr + 12, instance.model); - MatrixMath.writeUnsafe(ptr + 76, instance.normal); + ExtraMemoryOps.put2x16(ptr + 4, instance.overlay); + ExtraMemoryOps.put2x16(ptr + 8, instance.light); + ExtraMemoryOps.putMatrix4f(ptr + 12, instance.model); + ExtraMemoryOps.putMatrix3f(ptr + 76, instance.normal); }) .vertexShader(Flywheel.rl("instance/transformed.vert")) .cullShader(Flywheel.rl("instance/cull/transformed.glsl")) @@ -49,20 +47,15 @@ public final class InstanceTypes { MemoryUtil.memPutByte(ptr + 1, instance.g); MemoryUtil.memPutByte(ptr + 2, instance.b); MemoryUtil.memPutByte(ptr + 3, instance.a); - MemoryUtil.memPutShort(ptr + 4, (short) (instance.overlay & 0xFFFF)); - MemoryUtil.memPutShort(ptr + 6, (short) (instance.overlay >> 16 & 0xFFFF)); - MemoryUtil.memPutShort(ptr + 8, (short) (instance.packedLight & 0xFFFF)); - MemoryUtil.memPutShort(ptr + 10, (short) (instance.packedLight >> 16 & 0xFFFF)); + ExtraMemoryOps.put2x16(ptr + 4, instance.overlay); + ExtraMemoryOps.put2x16(ptr + 8, instance.light); MemoryUtil.memPutFloat(ptr + 12, instance.posX); MemoryUtil.memPutFloat(ptr + 16, instance.posY); MemoryUtil.memPutFloat(ptr + 20, instance.posZ); MemoryUtil.memPutFloat(ptr + 24, instance.pivotX); MemoryUtil.memPutFloat(ptr + 28, instance.pivotY); MemoryUtil.memPutFloat(ptr + 32, instance.pivotZ); - MemoryUtil.memPutFloat(ptr + 36, instance.rotation.x); - MemoryUtil.memPutFloat(ptr + 40, instance.rotation.y); - MemoryUtil.memPutFloat(ptr + 44, instance.rotation.z); - MemoryUtil.memPutFloat(ptr + 48, instance.rotation.w); + ExtraMemoryOps.putQuaternionf(ptr + 36, instance.rotation); }) .vertexShader(Flywheel.rl("instance/oriented.vert")) .cullShader(Flywheel.rl("instance/cull/oriented.glsl")) diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/math/MatrixMath.java b/common/src/lib/java/dev/engine_room/flywheel/lib/math/MatrixMath.java index a87334056..77a761b58 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/math/MatrixMath.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/math/MatrixMath.java @@ -7,25 +7,10 @@ import org.joml.Matrix4f; import org.lwjgl.system.MemoryUtil; -import com.mojang.blaze3d.vertex.PoseStack; - public final class MatrixMath { private MatrixMath() { } - public static PoseStack copyPoseStack(PoseStack stack) { - PoseStack copy = new PoseStack(); - copy.last() - .pose() - .set(stack.last() - .pose()); - copy.last() - .normal() - .set(stack.last() - .normal()); - return copy; - } - public static float transformPositionX(Matrix4f matrix, float x, float y, float z) { return fma(matrix.m00(), x, fma(matrix.m10(), y, fma(matrix.m20(), z, matrix.m30()))); } @@ -50,37 +35,6 @@ public static float transformNormalZ(Matrix3f matrix, float x, float y, float z) return fma(matrix.m02(), x, fma(matrix.m12(), y, matrix.m22() * z)); } - public static void writeUnsafe(long ptr, Matrix4f matrix) { - MemoryUtil.memPutFloat(ptr, matrix.m00()); - MemoryUtil.memPutFloat(ptr + 4, matrix.m01()); - MemoryUtil.memPutFloat(ptr + 8, matrix.m02()); - MemoryUtil.memPutFloat(ptr + 12, matrix.m03()); - MemoryUtil.memPutFloat(ptr + 16, matrix.m10()); - MemoryUtil.memPutFloat(ptr + 20, matrix.m11()); - MemoryUtil.memPutFloat(ptr + 24, matrix.m12()); - MemoryUtil.memPutFloat(ptr + 28, matrix.m13()); - MemoryUtil.memPutFloat(ptr + 32, matrix.m20()); - MemoryUtil.memPutFloat(ptr + 36, matrix.m21()); - MemoryUtil.memPutFloat(ptr + 40, matrix.m22()); - MemoryUtil.memPutFloat(ptr + 44, matrix.m23()); - MemoryUtil.memPutFloat(ptr + 48, matrix.m30()); - MemoryUtil.memPutFloat(ptr + 52, matrix.m31()); - MemoryUtil.memPutFloat(ptr + 56, matrix.m32()); - MemoryUtil.memPutFloat(ptr + 60, matrix.m33()); - } - - public static void writeUnsafe(long ptr, Matrix3f matrix) { - MemoryUtil.memPutFloat(ptr, matrix.m00()); - MemoryUtil.memPutFloat(ptr + 4, matrix.m01()); - MemoryUtil.memPutFloat(ptr + 8, matrix.m02()); - MemoryUtil.memPutFloat(ptr + 12, matrix.m10()); - MemoryUtil.memPutFloat(ptr + 16, matrix.m11()); - MemoryUtil.memPutFloat(ptr + 20, matrix.m12()); - MemoryUtil.memPutFloat(ptr + 24, matrix.m20()); - MemoryUtil.memPutFloat(ptr + 28, matrix.m21()); - MemoryUtil.memPutFloat(ptr + 32, matrix.m22()); - } - /** * Extracts the greatest scale factor across all axes from the given matrix. * diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/AtomicBitset.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/AtomicBitSet.java similarity index 93% rename from common/src/lib/java/dev/engine_room/flywheel/lib/util/AtomicBitset.java rename to common/src/lib/java/dev/engine_room/flywheel/lib/util/AtomicBitSet.java index ea59e846d..28532b70d 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/util/AtomicBitset.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/util/AtomicBitSet.java @@ -9,7 +9,7 @@ // https://github.com/Netflix/hollow/blob/master/hollow/src/main/java/com/netflix/hollow/core/memory/ThreadSafeBitSet.java // Refactored to remove unused methods, deduplicate some code segments, and add extra functionality with #forEachSetSpan -public class AtomicBitset { +public class AtomicBitSet { // 1024 bits, 128 bytes, 16 longs per segment public static final int DEFAULT_LOG2_SEGMENT_SIZE_IN_BITS = 10; @@ -18,17 +18,17 @@ public class AtomicBitset { private final int numLongsPerSegment; private final int log2SegmentSize; private final int segmentMask; - private final AtomicReference segments; + private final AtomicReference segments; - public AtomicBitset() { + public AtomicBitSet() { this(DEFAULT_LOG2_SEGMENT_SIZE_IN_BITS); } - public AtomicBitset(int log2SegmentSizeInBits) { + public AtomicBitSet(int log2SegmentSizeInBits) { this(log2SegmentSizeInBits, 0); } - public AtomicBitset(int log2SegmentSizeInBits, int numBitsToPreallocate) { + public AtomicBitSet(int log2SegmentSizeInBits, int numBitsToPreallocate) { if (log2SegmentSizeInBits < 6) { throw new IllegalArgumentException("Cannot specify fewer than 64 bits in each segment!"); } @@ -40,7 +40,7 @@ public AtomicBitset(int log2SegmentSizeInBits, int numBitsToPreallocate) { long numBitsPerSegment = numLongsPerSegment * 64L; int numSegmentsToPreallocate = numBitsToPreallocate == 0 ? 1 : (int) (((numBitsToPreallocate - 1) / numBitsPerSegment) + 1); - segments = new AtomicReference<>(new AtomicBitsetSegments(numSegmentsToPreallocate, numLongsPerSegment)); + segments = new AtomicReference<>(new AtomicBitSetSegments(numSegmentsToPreallocate, numLongsPerSegment)); } public void set(int position) { @@ -251,7 +251,7 @@ public boolean get(int position) { } public long maxSetBit() { - AtomicBitsetSegments segments = this.segments.get(); + AtomicBitSetSegments segments = this.segments.get(); int segmentIdx = segments.numSegments() - 1; @@ -273,7 +273,7 @@ public int nextSetBit(int fromIndex) { throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex); } - AtomicBitsetSegments segments = this.segments.get(); + AtomicBitSetSegments segments = this.segments.get(); int segmentPosition = segmentIndexForPosition(fromIndex); if (segmentPosition >= segments.numSegments()) { @@ -309,7 +309,7 @@ public int nextClearBit(int fromIndex) { int segmentPosition = segmentIndexForPosition(fromIndex); - AtomicBitsetSegments segments = this.segments.get(); + AtomicBitSetSegments segments = this.segments.get(); if (segmentPosition >= segments.numSegments()) { return fromIndex; @@ -352,7 +352,7 @@ public int cardinality() { * @param consumer The consumer to accept each span. */ public void forEachSetSpan(BitSpanConsumer consumer) { - AtomicBitsetSegments segments = this.segments.get(); + AtomicBitSetSegments segments = this.segments.get(); if (segments.cardinality() == 0) { return; @@ -415,7 +415,7 @@ public boolean isEmpty() { * Clear all bits to 0. */ public void clear() { - AtomicBitsetSegments segments = this.segments.get(); + AtomicBitSetSegments segments = this.segments.get(); for (int i = 0; i < segments.numSegments(); i++) { AtomicLongArray segment = segments.getSegment(i); @@ -478,13 +478,13 @@ private AtomicLongArray segmentForPosition(int segmentIndex) { } @NotNull - private AtomicBitsetSegments expandToFit(int segmentIndex) { - AtomicBitsetSegments visibleSegments = segments.get(); + private AtomicBitSet.AtomicBitSetSegments expandToFit(int segmentIndex) { + AtomicBitSetSegments visibleSegments = segments.get(); while (visibleSegments.numSegments() <= segmentIndex) { // Thread safety: newVisibleSegments contains all of the segments from the currently visible segments, plus extra. // all of the segments in the currently visible segments are canonical and will not change. - AtomicBitsetSegments newVisibleSegments = new AtomicBitsetSegments(visibleSegments, segmentIndex + 1, numLongsPerSegment); + AtomicBitSetSegments newVisibleSegments = new AtomicBitSetSegments(visibleSegments, segmentIndex + 1, numLongsPerSegment); // because we are using a compareAndSet, if this thread "wins the race" and successfully sets this variable, then the segments // which are newly defined in newVisibleSegments become canonical. @@ -500,10 +500,10 @@ private AtomicBitsetSegments expandToFit(int segmentIndex) { return visibleSegments; } - private static class AtomicBitsetSegments { + private static class AtomicBitSetSegments { private final AtomicLongArray[] segments; - private AtomicBitsetSegments(int numSegments, int segmentLength) { + private AtomicBitSetSegments(int numSegments, int segmentLength) { AtomicLongArray[] segments = new AtomicLongArray[numSegments]; for (int i = 0; i < numSegments; i++) { @@ -515,7 +515,7 @@ private AtomicBitsetSegments(int numSegments, int segmentLength) { this.segments = segments; } - private AtomicBitsetSegments(AtomicBitsetSegments copyFrom, int numSegments, int segmentLength) { + private AtomicBitSetSegments(AtomicBitSetSegments copyFrom, int numSegments, int segmentLength) { AtomicLongArray[] segments = new AtomicLongArray[numSegments]; for (int i = 0; i < numSegments; i++) { @@ -550,7 +550,7 @@ public AtomicLongArray getSegment(int index) { @Override public boolean equals(Object obj) { - if (!(obj instanceof AtomicBitset other)) { + if (!(obj instanceof AtomicBitSet other)) { return false; } @@ -558,8 +558,8 @@ public boolean equals(Object obj) { throw new IllegalArgumentException("Segment sizes must be the same"); } - AtomicBitsetSegments thisSegments = this.segments.get(); - AtomicBitsetSegments otherSegments = other.segments.get(); + AtomicBitSetSegments thisSegments = this.segments.get(); + AtomicBitSetSegments otherSegments = other.segments.get(); for (int i = 0; i < thisSegments.numSegments(); i++) { AtomicLongArray thisArray = thisSegments.getSegment(i); diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ExtraMemoryOps.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/ExtraMemoryOps.java new file mode 100644 index 000000000..3840129be --- /dev/null +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/util/ExtraMemoryOps.java @@ -0,0 +1,82 @@ +package dev.engine_room.flywheel.lib.util; + +import org.joml.Matrix3fc; +import org.joml.Matrix4fc; +import org.joml.Quaternionfc; +import org.joml.Vector2fc; +import org.joml.Vector3fc; +import org.joml.Vector4fc; +import org.lwjgl.system.MemoryUtil; + +public final class ExtraMemoryOps { + private ExtraMemoryOps() { + } + + public static void put4x8(long ptr, int value) { + MemoryUtil.memPutByte(ptr, (byte) (value & 0xFF)); + MemoryUtil.memPutByte(ptr + 1, (byte) (value >>> 8 & 0xFF)); + MemoryUtil.memPutByte(ptr + 2, (byte) (value >>> 16 & 0xFF)); + MemoryUtil.memPutByte(ptr + 3, (byte) (value >>> 24 & 0xFF)); + } + + public static void put2x16(long ptr, int value) { + MemoryUtil.memPutShort(ptr, (short) (value & 0xFFFF)); + MemoryUtil.memPutShort(ptr + 2, (short) (value >>> 16 & 0xFFFF)); + } + + public static void putVector2f(long ptr, Vector2fc vector) { + MemoryUtil.memPutFloat(ptr, vector.x()); + MemoryUtil.memPutFloat(ptr + 4, vector.y()); + } + + public static void putVector3f(long ptr, Vector3fc vector) { + MemoryUtil.memPutFloat(ptr, vector.x()); + MemoryUtil.memPutFloat(ptr + 4, vector.y()); + MemoryUtil.memPutFloat(ptr + 8, vector.z()); + } + + public static void putVector4f(long ptr, Vector4fc vector) { + MemoryUtil.memPutFloat(ptr, vector.x()); + MemoryUtil.memPutFloat(ptr + 4, vector.y()); + MemoryUtil.memPutFloat(ptr + 8, vector.z()); + MemoryUtil.memPutFloat(ptr + 12, vector.w()); + } + + public static void putQuaternionf(long ptr, Quaternionfc quaternion) { + MemoryUtil.memPutFloat(ptr, quaternion.x()); + MemoryUtil.memPutFloat(ptr + 4, quaternion.y()); + MemoryUtil.memPutFloat(ptr + 8, quaternion.z()); + MemoryUtil.memPutFloat(ptr + 12, quaternion.w()); + } + + public static void putMatrix3f(long ptr, Matrix3fc matrix) { + MemoryUtil.memPutFloat(ptr, matrix.m00()); + MemoryUtil.memPutFloat(ptr + 4, matrix.m01()); + MemoryUtil.memPutFloat(ptr + 8, matrix.m02()); + MemoryUtil.memPutFloat(ptr + 12, matrix.m10()); + MemoryUtil.memPutFloat(ptr + 16, matrix.m11()); + MemoryUtil.memPutFloat(ptr + 20, matrix.m12()); + MemoryUtil.memPutFloat(ptr + 24, matrix.m20()); + MemoryUtil.memPutFloat(ptr + 28, matrix.m21()); + MemoryUtil.memPutFloat(ptr + 32, matrix.m22()); + } + + public static void putMatrix4f(long ptr, Matrix4fc matrix) { + MemoryUtil.memPutFloat(ptr, matrix.m00()); + MemoryUtil.memPutFloat(ptr + 4, matrix.m01()); + MemoryUtil.memPutFloat(ptr + 8, matrix.m02()); + MemoryUtil.memPutFloat(ptr + 12, matrix.m03()); + MemoryUtil.memPutFloat(ptr + 16, matrix.m10()); + MemoryUtil.memPutFloat(ptr + 20, matrix.m11()); + MemoryUtil.memPutFloat(ptr + 24, matrix.m12()); + MemoryUtil.memPutFloat(ptr + 28, matrix.m13()); + MemoryUtil.memPutFloat(ptr + 32, matrix.m20()); + MemoryUtil.memPutFloat(ptr + 36, matrix.m21()); + MemoryUtil.memPutFloat(ptr + 40, matrix.m22()); + MemoryUtil.memPutFloat(ptr + 44, matrix.m23()); + MemoryUtil.memPutFloat(ptr + 48, matrix.m30()); + MemoryUtil.memPutFloat(ptr + 52, matrix.m31()); + MemoryUtil.memPutFloat(ptr + 56, matrix.m32()); + MemoryUtil.memPutFloat(ptr + 60, matrix.m33()); + } +} diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractBlockEntityVisual.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractBlockEntityVisual.java index bdecdb4c4..59722198e 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractBlockEntityVisual.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractBlockEntityVisual.java @@ -11,7 +11,9 @@ import dev.engine_room.flywheel.api.visual.TickableVisual; import dev.engine_room.flywheel.api.visualization.VisualManager; import dev.engine_room.flywheel.api.visualization.VisualizationContext; +import dev.engine_room.flywheel.lib.instance.FlatLit; import dev.engine_room.flywheel.lib.math.MoreMath; +import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.core.BlockPos; import net.minecraft.core.SectionPos; import net.minecraft.world.level.block.entity.BlockEntity; @@ -40,8 +42,8 @@ public abstract class AbstractBlockEntityVisual extends A @Nullable protected LitVisual.Notifier notifier; - public AbstractBlockEntityVisual(VisualizationContext ctx, T blockEntity) { - super(ctx, blockEntity.getLevel()); + public AbstractBlockEntityVisual(VisualizationContext ctx, T blockEntity, float partialTick) { + super(ctx, blockEntity.getLevel(), partialTick); this.blockEntity = blockEntity; this.pos = blockEntity.getBlockPos(); this.blockState = blockEntity.getBlockState(); @@ -49,8 +51,8 @@ public AbstractBlockEntityVisual(VisualizationContext ctx, T blockEntity) { } @Override - public void init(float partialTick) { - updateLight(); + public void setLightSectionNotifier(Notifier notifier) { + this.notifier = notifier; } @Override @@ -58,11 +60,6 @@ public void collectLightSections(LongConsumer consumer) { consumer.accept(SectionPos.asLong(pos)); } - @Override - public void initLightSectionNotifier(Notifier notifier) { - this.notifier = notifier; - } - /** * In order to accommodate for floating point precision errors at high coordinates, * {@link VisualManager}s are allowed to arbitrarily adjust the origin, and @@ -100,4 +97,12 @@ public boolean doDistanceLimitThisFrame(DynamicVisual.Context context) { return !context.limiter() .shouldUpdate(pos.distToCenterSqr(context.camera().getPosition())); } + + protected void relight(BlockPos pos, @Nullable FlatLit... instances) { + FlatLit.relight(LevelRenderer.getLightColor(level, pos), instances); + } + + protected void relight(@Nullable FlatLit... instances) { + relight(pos, instances); + } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractEntityVisual.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractEntityVisual.java index e675a63b4..0cff1c953 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractEntityVisual.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractEntityVisual.java @@ -8,8 +8,12 @@ import dev.engine_room.flywheel.api.visual.TickableVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.api.visualization.VisualizationManager; +import dev.engine_room.flywheel.lib.instance.FlatLit; +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.LightLayer; import net.minecraft.world.phys.Vec3; /** @@ -31,16 +35,12 @@ public abstract class AbstractEntityVisual extends AbstractVis protected final T entity; protected final EntityVisibilityTester visibilityTester; - public AbstractEntityVisual(VisualizationContext ctx, T entity) { - super(ctx, entity.level()); + public AbstractEntityVisual(VisualizationContext ctx, T entity, float partialTick) { + super(ctx, entity.level(), partialTick); this.entity = entity; visibilityTester = new EntityVisibilityTester(entity, ctx.renderOrigin(), 1.5f); } - @Override - public void init(float partialTick) { - } - /** * Calculate the distance squared between this visual and the given level position. * @@ -84,4 +84,12 @@ public Vector3f getVisualPosition(float partialTick) { public boolean isVisible(FrustumIntersection frustum) { return entity.noCulling || visibilityTester.check(frustum); } + + protected void relight(float partialTick, FlatLit... instances) { + BlockPos pos = BlockPos.containing(entity.getLightProbePosition(partialTick)); + int blockLight = entity.isOnFire() ? 15 : level.getBrightness(LightLayer.BLOCK, pos); + int skyLight = level.getBrightness(LightLayer.SKY, pos); + int light = LightTexture.pack(blockLight, skyLight); + FlatLit.relight(light, instances); + } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractVisual.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractVisual.java index ce43eca96..c21866435 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractVisual.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/AbstractVisual.java @@ -1,18 +1,10 @@ package dev.engine_room.flywheel.lib.visual; -import java.util.Objects; -import java.util.stream.Stream; - -import org.jetbrains.annotations.Nullable; - import dev.engine_room.flywheel.api.instance.InstancerProvider; import dev.engine_room.flywheel.api.visual.Visual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; -import dev.engine_room.flywheel.lib.instance.FlatLit; -import net.minecraft.core.BlockPos; import net.minecraft.core.Vec3i; import net.minecraft.world.level.Level; -import net.minecraft.world.level.LightLayer; public abstract class AbstractVisual implements Visual { /** @@ -27,7 +19,7 @@ public abstract class AbstractVisual implements Visual { protected boolean deleted = false; - public AbstractVisual(VisualizationContext ctx, Level level) { + public AbstractVisual(VisualizationContext ctx, Level level, float partialTick) { this.visualizationContext = ctx; this.instancerProvider = ctx.instancerProvider(); this.renderOrigin = ctx.renderOrigin(); @@ -49,46 +41,4 @@ public final void delete() { _delete(); deleted = true; } - - protected void relight(BlockPos pos, @Nullable FlatLit... instances) { - relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), instances); - } - - protected void relight(int block, int sky, @Nullable FlatLit... instances) { - for (FlatLit instance : instances) { - if (instance == null) { - continue; - } - - instance.light(block, sky) - .handle() - .setChanged(); - } - } - - protected void relight(BlockPos pos, Stream instances) { - relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), instances); - } - - protected void relight(int block, int sky, Stream instances) { - instances.filter(Objects::nonNull) - .forEach(instance -> instance.light(block, sky) - .handle() - .setChanged()); - } - - protected void relight(BlockPos pos, Iterable instances) { - relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), instances); - } - - protected void relight(int block, int sky, Iterable instances) { - for (FlatLit instance : instances) { - if (instance == null) { - continue; - } - instance.light(block, sky) - .handle() - .setChanged(); - } - } } diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleBlockEntityVisualizer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleBlockEntityVisualizer.java index ab60f3d4c..d3c302d45 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleBlockEntityVisualizer.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleBlockEntityVisualizer.java @@ -1,5 +1,6 @@ package dev.engine_room.flywheel.lib.visual; +import java.util.List; import java.util.Objects; import java.util.function.Predicate; @@ -23,8 +24,8 @@ public SimpleBlockEntityVisualizer(Factory visualFactory, Predicate skipVa } @Override - public BlockEntityVisual createVisual(VisualizationContext ctx, T blockEntity) { - return visualFactory.create(ctx, blockEntity); + public List> createVisual(VisualizationContext ctx, T blockEntity, float partialTick) { + return List.of(visualFactory.create(ctx, blockEntity, partialTick)); } @Override @@ -45,7 +46,7 @@ public static Builder builder(BlockEntityType type @FunctionalInterface public interface Factory { - BlockEntityVisual create(VisualizationContext ctx, T blockEntity); + BlockEntityVisual create(VisualizationContext ctx, T blockEntity, float partialTick); } /** diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleEntityVisual.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleEntityVisual.java index 0af57ec5b..35bb8b3a5 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleEntityVisual.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleEntityVisual.java @@ -9,8 +9,8 @@ public class SimpleEntityVisual extends AbstractEntityVisual implements SimpleDynamicVisual { protected final List components = new ArrayList<>(); - public SimpleEntityVisual(VisualizationContext ctx, T entity) { - super(ctx, entity); + public SimpleEntityVisual(VisualizationContext ctx, T entity, float partialTick) { + super(ctx, entity, partialTick); } public void addComponent(EntityComponent component) { diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleEntityVisualizer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleEntityVisualizer.java index 4e908cdce..4757dc6ff 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleEntityVisualizer.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/SimpleEntityVisualizer.java @@ -1,5 +1,6 @@ package dev.engine_room.flywheel.lib.visual; +import java.util.List; import java.util.Objects; import java.util.function.Predicate; @@ -23,8 +24,8 @@ public SimpleEntityVisualizer(Factory visualFactory, Predicate skipVanilla } @Override - public EntityVisual createVisual(VisualizationContext ctx, T entity) { - return visualFactory.create(ctx, entity); + public List> createVisual(VisualizationContext ctx, T entity, float partialTick) { + return List.of(visualFactory.create(ctx, entity, partialTick)); } @Override @@ -45,7 +46,7 @@ public static Builder builder(EntityType type) { @FunctionalInterface public interface Factory { - EntityVisual create(VisualizationContext ctx, T entity); + EntityVisual create(VisualizationContext ctx, T entity, float partialTick); } /** diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/HitboxComponent.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/HitboxComponent.java index f0cacfc2c..36277dfa9 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/HitboxComponent.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/HitboxComponent.java @@ -109,7 +109,7 @@ public void beginFrame(DynamicVisual.Context context) { .loadIdentity() .translate(entityX - bbWidthHalf, entityY + entity.getEyeHeight() - 0.01, entityZ - bbWidthHalf) .scale(bbWidth, 0.02f, bbWidth) - .setColor(255, 0, 0) + .color(255, 0, 0) .setChanged(); } @@ -119,7 +119,7 @@ public void beginFrame(DynamicVisual.Context context) { .loadIdentity() .translate(entityX, entityY + entity.getEyeHeight(), entityZ) .rotate(new Quaternionf().rotateTo(0, 1, 0, (float) viewVector.x, (float) viewVector.y, (float) viewVector.z)) - .setColor(0, 0, 255) + .color(0, 0, 255) .setChanged(); } diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java index e0accaf2d..c9ac5d420 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizationManagerImpl.java @@ -17,6 +17,7 @@ import dev.engine_room.flywheel.api.instance.Instance; import dev.engine_room.flywheel.api.task.Plan; import dev.engine_room.flywheel.api.task.TaskExecutor; +import dev.engine_room.flywheel.api.visual.BlockEntityVisual; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.Effect; import dev.engine_room.flywheel.api.visual.TickableVisual; @@ -261,21 +262,23 @@ public void renderCrumbling(RenderContext context, Long2ObjectMap instances = new ArrayList<>(); - visual.collectCrumblingInstances(instance -> { - if (instance != null) { - instances.add(instance); - } - }); + for (BlockEntityVisual visual : visualList) { + visual.collectCrumblingInstances(instance -> { + if (instance != null) { + instances.add(instance); + } + }); + } if (instances.isEmpty()) { // The visual doesn't want to render anything crumbling. diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/BlockEntityStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/BlockEntityStorage.java index b61a3824f..d89273dcc 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/BlockEntityStorage.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/BlockEntityStorage.java @@ -1,11 +1,11 @@ package dev.engine_room.flywheel.impl.visualization.manager; +import java.util.List; import java.util.function.Supplier; import org.jetbrains.annotations.Nullable; import dev.engine_room.flywheel.api.visual.BlockEntityVisual; -import dev.engine_room.flywheel.api.visual.Visual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.impl.visualization.storage.Storage; import dev.engine_room.flywheel.lib.visual.VisualizationHelper; @@ -17,14 +17,14 @@ import net.minecraft.world.level.block.entity.BlockEntity; public class BlockEntityStorage extends Storage { - private final Long2ObjectMap> posLookup = new Long2ObjectOpenHashMap<>(); + private final Long2ObjectMap>> posLookup = new Long2ObjectOpenHashMap<>(); public BlockEntityStorage(Supplier visualizationContextSupplier) { super(visualizationContextSupplier); } @Nullable - public BlockEntityVisual visualAtPos(long pos) { + public List> visualAtPos(long pos) { return posLookup.get(pos); } @@ -53,19 +53,18 @@ public boolean willAccept(BlockEntity blockEntity) { } @Override - @Nullable - protected Visual createRaw(BlockEntity obj) { + protected List> createRaw(BlockEntity obj, float partialTick) { var visualizer = VisualizationHelper.getVisualizer(obj); if (visualizer == null) { - return null; + return List.of(); } - var visual = visualizer.createVisual(visualizationContextSupplier.get(), obj); + var visualList = visualizer.createVisual(visualizationContextSupplier.get(), obj, partialTick); BlockPos blockPos = obj.getBlockPos(); - posLookup.put(blockPos.asLong(), visual); + posLookup.put(blockPos.asLong(), visualList); - return visual; + return visualList; } @Override diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/EffectStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/EffectStorage.java index 2d7816337..a59ef7e85 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/EffectStorage.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/EffectStorage.java @@ -1,5 +1,6 @@ package dev.engine_room.flywheel.impl.visualization.manager; +import java.util.List; import java.util.function.Supplier; import dev.engine_room.flywheel.api.visual.Effect; @@ -13,8 +14,8 @@ public EffectStorage(Supplier visualizationContextSupplier } @Override - protected EffectVisual createRaw(Effect obj) { - return obj.visualize(visualizationContextSupplier.get()); + protected List> createRaw(Effect obj, float partialTick) { + return obj.visualize(visualizationContextSupplier.get(), partialTick); } @Override diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/EntityStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/EntityStorage.java index 0d5666880..eed2e0f2d 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/EntityStorage.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/EntityStorage.java @@ -1,10 +1,9 @@ package dev.engine_room.flywheel.impl.visualization.manager; +import java.util.List; import java.util.function.Supplier; -import org.jetbrains.annotations.Nullable; - -import dev.engine_room.flywheel.api.visual.Visual; +import dev.engine_room.flywheel.api.visual.EntityVisual; import dev.engine_room.flywheel.api.visualization.VisualizationContext; import dev.engine_room.flywheel.impl.visualization.storage.Storage; import dev.engine_room.flywheel.lib.visual.VisualizationHelper; @@ -17,14 +16,13 @@ public EntityStorage(Supplier visualizationContextSupplier } @Override - @Nullable - protected Visual createRaw(Entity obj) { + protected List> createRaw(Entity obj, float partialTick) { var visualizer = VisualizationHelper.getVisualizer(obj); if (visualizer == null) { - return null; + return List.of(); } - return visualizer.createVisual(visualizationContextSupplier.get(), obj); + return visualizer.createVisual(visualizationContextSupplier.get(), obj, partialTick); } @Override diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/VisualManagerImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/VisualManagerImpl.java index 800714cb5..ea385a634 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/VisualManagerImpl.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/manager/VisualManagerImpl.java @@ -26,7 +26,7 @@ public S getStorage() { @Override public int getVisualCount() { - return getStorage().getAllVisuals().size(); + return getStorage().visualCount(); } @Override diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LitVisualStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LitVisualStorage.java index 884a5f759..3651fe278 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LitVisualStorage.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/LitVisualStorage.java @@ -51,11 +51,12 @@ public Plan plan() { }); long updateId = getNextUpdateId(); + Updater.Context updaterContext = new Updater.Context(updateId, context.partialTick()); for (long section : sectionsUpdatedThisFrame) { var visuals = sections2Visuals.get(section); if (visuals != null && !visuals.isEmpty()) { - taskExecutor.execute(() -> Distribute.tasks(taskExecutor, updateId, sync, visuals, Updater::updateLight)); + taskExecutor.execute(() -> Distribute.tasks(taskExecutor, updaterContext, sync, visuals, Updater::updateLight)); } else { sync.decrementAndEventuallyRun(); } @@ -89,8 +90,8 @@ public boolean isEmpty() { return visuals2Sections.isEmpty(); } - public void addAndInitNotifier(LitVisual visual) { - visual.initLightSectionNotifier(new LitVisualNotifierImpl(visual)); + public void setNotifierAndAdd(LitVisual visual) { + visual.setLightSectionNotifier(new LitVisualNotifierImpl(visual)); add(visual); } @@ -168,15 +169,15 @@ private static Updater createUpdater(LitVisual visual, int sectionCount) { // Breaking this into 2 separate cases allows us to avoid the overhead of atomics in the common case. sealed interface Updater { - void updateLight(long updateId); + void updateLight(Context ctx); LitVisual visual(); // The visual is only in one section. In this case, we can just update the visual directly. record Simple(LitVisual visual) implements Updater { @Override - public void updateLight(long updateId) { - visual.updateLight(); + public void updateLight(Context ctx) { + visual.updateLight(ctx.partialTick); } } @@ -184,14 +185,17 @@ public void updateLight(long updateId) { // even when multiple sections it was contained in are updated at the same time. record Synced(LitVisual visual, AtomicLong updateId) implements Updater { @Override - public void updateLight(long updateId) { + public void updateLight(Context ctx) { // Different update ID means we won, so we can update the visual. // Same update ID means another thread beat us to the update. - if (this.updateId.getAndSet(updateId) != updateId) { - visual.updateLight(); + if (this.updateId.getAndSet(ctx.updateId) != ctx.updateId) { + visual.updateLight(ctx.partialTick); } } } + + record Context(long updateId, float partialTick) { + } } private final class LitVisualNotifierImpl implements LitVisual.Notifier { diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java index 1c245e499..58c8ce42b 100644 --- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java +++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/Storage.java @@ -1,13 +1,10 @@ package dev.engine_room.flywheel.impl.visualization.storage; import java.util.ArrayList; -import java.util.Collection; import java.util.List; import java.util.Map; import java.util.function.Supplier; -import org.jetbrains.annotations.Nullable; - import dev.engine_room.flywheel.api.task.Plan; import dev.engine_room.flywheel.api.visual.DynamicVisual; import dev.engine_room.flywheel.api.visual.LitVisual; @@ -29,59 +26,50 @@ public abstract class Storage { protected final List simpleTickableVisuals = new ArrayList<>(); protected final LitVisualStorage litVisuals = new LitVisualStorage(); - private final Map visuals = new Reference2ObjectOpenHashMap<>(); + private final Map> visuals = new Reference2ObjectOpenHashMap<>(); public Storage(Supplier visualizationContextSupplier) { this.visualizationContextSupplier = visualizationContextSupplier; } - public Collection getAllVisuals() { - return visuals.values(); + public int visualCount() { + int out = 0; + for (var visualList : visuals.values()) { + out += visualList.size(); + } + return out; } public void add(T obj, float partialTick) { - Visual visual = visuals.get(obj); + var visualList = this.visuals.get(obj); - if (visual == null) { + if (visualList == null) { create(obj, partialTick); } } public void remove(T obj) { - Visual visual = visuals.remove(obj); + var visualList = this.visuals.remove(obj); - if (visual == null) { + if (visualList == null || visualList.isEmpty()) { return; } - if (visual instanceof TickableVisual tickable) { - if (visual instanceof SimpleTickableVisual simpleTickable) { - simpleTickableVisuals.remove(simpleTickable); - } else { - tickableVisuals.remove(tickable); - } - } - if (visual instanceof DynamicVisual dynamic) { - if (visual instanceof SimpleDynamicVisual simpleDynamic) { - simpleDynamicVisuals.remove(simpleDynamic); - } else { - dynamicVisuals.remove(dynamic); - } - } - if (visual instanceof LitVisual lit) { - litVisuals.remove(lit); + for (Visual visual : visualList) { + remove(visual); } - visual.delete(); } public void update(T obj, float partialTick) { - Visual visual = visuals.get(obj); + var visualList = visuals.get(obj); - if (visual == null) { + if (visualList == null || visualList.isEmpty()) { return; } - visual.update(partialTick); + for (Visual visual : visualList) { + visual.update(partialTick); + } } public void recreateAll(float partialTick) { @@ -90,13 +78,17 @@ public void recreateAll(float partialTick) { simpleTickableVisuals.clear(); simpleDynamicVisuals.clear(); litVisuals.clear(); - visuals.replaceAll((obj, visual) -> { - visual.delete(); + visuals.replaceAll((obj, visuals) -> { + visuals.forEach(Visual::delete); + + var out = createRaw(obj, partialTick); - Visual out = createRaw(obj); + if (out.isEmpty()) { + return null; + } - if (out != null) { - setup(out, partialTick); + for (Visual visual : out) { + setup(visual); } return out; @@ -107,22 +99,28 @@ public void invalidate() { tickableVisuals.clear(); dynamicVisuals.clear(); litVisuals.clear(); - visuals.values() - .forEach(Visual::delete); + for (var visualList : visuals.values()) { + for (Visual visual : visualList) { + visual.delete(); + } + } visuals.clear(); } private void create(T obj, float partialTick) { - Visual visual = createRaw(obj); + var visuals = createRaw(obj, partialTick); - if (visual != null) { - setup(visual, partialTick); - visuals.put(obj, visual); + if (visuals.isEmpty()) { + return; + } + this.visuals.put(obj, visuals); + + for (Visual visual : visuals) { + setup(visual); } } - @Nullable - protected abstract Visual createRaw(T obj); + protected abstract List createRaw(T obj, float partialTick); public Plan framePlan() { return NestedPlan.of(dynamicVisuals, litVisuals.plan(), ForEachPlan.of(() -> simpleDynamicVisuals, SimpleDynamicVisual::beginFrame)); @@ -136,9 +134,7 @@ public void enqueueLightUpdateSection(long section) { litVisuals.enqueueLightUpdateSection(section); } - private void setup(Visual visual, float partialTick) { - visual.init(partialTick); - + private void setup(Visual visual) { if (visual instanceof TickableVisual tickable) { if (visual instanceof SimpleTickableVisual simpleTickable) { simpleTickableVisuals.add(simpleTickable); @@ -156,8 +152,29 @@ private void setup(Visual visual, float partialTick) { } if (visual instanceof LitVisual lit) { - litVisuals.addAndInitNotifier(lit); + litVisuals.setNotifierAndAdd(lit); + } + } + + private void remove(Visual visual) { + if (visual instanceof TickableVisual tickable) { + if (visual instanceof SimpleTickableVisual simpleTickable) { + simpleTickableVisuals.remove(simpleTickable); + } else { + tickableVisuals.remove(tickable); + } + } + if (visual instanceof DynamicVisual dynamic) { + if (visual instanceof SimpleDynamicVisual simpleDynamic) { + simpleDynamicVisuals.remove(simpleDynamic); + } else { + dynamicVisuals.remove(dynamic); + } + } + if (visual instanceof LitVisual lit) { + litVisuals.remove(lit); } + visual.delete(); } /** diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/BellVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/BellVisual.java index 12ae9fcd4..9a81b2ae4 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/BellVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/BellVisual.java @@ -26,24 +26,19 @@ public class BellVisual extends AbstractBlockEntityVisual imple return new SingleMeshModel(ModelPartConverter.convert(ModelLayers.BELL, BellRenderer.BELL_RESOURCE_LOCATION.sprite(), "bell_body"), Materials.BELL); }); - private OrientedInstance bell; + private final OrientedInstance bell; private boolean wasShaking = false; - public BellVisual(VisualizationContext ctx, BellBlockEntity blockEntity) { - super(ctx, blockEntity); - } + public BellVisual(VisualizationContext ctx, BellBlockEntity blockEntity, float partialTick) { + super(ctx, blockEntity, partialTick); - @Override - public void init(float partialTick) { bell = createBellInstance().setPivot(0.5f, 0.75f, 0.5f) .setPosition(getVisualPosition()); - bell.setChanged(); updateRotation(partialTick); - - super.init(partialTick); + updateLight(partialTick); } private OrientedInstance createBellInstance() { @@ -81,8 +76,8 @@ private void updateRotation(float partialTick) { } @Override - public void updateLight() { - relight(pos, bell); + public void updateLight(float partialTick) { + relight(bell); } @Override diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/ChestVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/ChestVisual.java index 42c31200e..32c77be61 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/ChestVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/ChestVisual.java @@ -51,22 +51,20 @@ public class ChestVisual extends Abstrac return new SingleMeshModel(ModelPartConverter.convert(LAYER_LOCATIONS.get(key.first()), key.second().sprite(), "lock"), Materials.CHEST); }); - private OrientedInstance bottom; - private TransformedInstance lid; - private TransformedInstance lock; + private final OrientedInstance bottom; + private final TransformedInstance lid; + private final TransformedInstance lock; + + private final ChestType chestType; + private final Float2FloatFunction lidProgress; - private ChestType chestType; private final Quaternionf baseRotation = new Quaternionf(); - private Float2FloatFunction lidProgress; private float lastProgress = Float.NaN; - public ChestVisual(VisualizationContext ctx, T blockEntity) { - super(ctx, blockEntity); - } + public ChestVisual(VisualizationContext ctx, T blockEntity, float partialTick) { + super(ctx, blockEntity, partialTick); - @Override - public void init(float partialTick) { chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE; Material texture = Sheets.chooseMaterial(blockEntity, chestType, isChristmas()); @@ -90,8 +88,7 @@ public void init(float partialTick) { bottom.setChanged(); applyLidTransform(lidProgress.get(partialTick)); - - super.init(partialTick); + updateLight(partialTick); } private OrientedInstance createBottomInstance(Material texture) { @@ -153,8 +150,8 @@ private void applyLidTransform(float progress) { } @Override - public void updateLight() { - relight(pos, bottom, lid, lock); + public void updateLight(float partialTick) { + relight(bottom, lid, lock); } @Override diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java index a4c27ee82..b0a72f0a7 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/MinecartVisual.java @@ -38,41 +38,38 @@ public class MinecartVisual extends SimpleEntityVisu public static final ModelHolder SPAWNER_BODY_MODEL = createBodyModelHolder(ModelLayers.SPAWNER_MINECART); public static final ModelHolder TNT_BODY_MODEL = createBodyModelHolder(ModelLayers.TNT_MINECART); - private final ModelHolder bodyModel; - - private TransformedInstance body; + private final TransformedInstance body; @Nullable private TransformedInstance contents; + + private final ModelHolder bodyModel; + + private final PoseStack stack = new PoseStack(); + private BlockState blockState; private boolean active; - private final PoseStack stack = new PoseStack(); + public MinecartVisual(VisualizationContext ctx, T entity, float partialTick, ModelHolder bodyModel) { + super(ctx, entity, partialTick); - public MinecartVisual(VisualizationContext ctx, T entity, ModelHolder bodyModel) { - super(ctx, entity); this.bodyModel = bodyModel; - } - private static ModelHolder createBodyModelHolder(ModelLayerLocation layer) { - return new ModelHolder(() -> { - return new SingleMeshModel(ModelPartConverter.convert(layer), Materials.MINECART); - }); - } + body = createBodyInstance(); + blockState = entity.getDisplayBlockState(); + contents = createContentsInstance(); - @Override - public void init(float partialTick) { addComponent(new ShadowComponent(visualizationContext, entity).radius(0.7f)); addComponent(new FireComponent(visualizationContext, entity)); addComponent(new HitboxComponent(visualizationContext, entity)); - body = createBodyInstance(); - blockState = entity.getDisplayBlockState(); - contents = createContentsInstance(); - updateInstances(partialTick); - updateLight(); + updateLight(partialTick); + } - super.init(partialTick); + private static ModelHolder createBodyModelHolder(ModelLayerLocation layer) { + return new ModelHolder(() -> { + return new SingleMeshModel(ModelPartConverter.convert(layer), Materials.MINECART); + }); } private TransformedInstance createBodyInstance() { @@ -110,8 +107,6 @@ public void tick(TickableVisual.Context context) { } contents = createContentsInstance(); } - - updateLight(); } @Override @@ -198,6 +193,9 @@ private void updateInstances(float partialTick) { stack.scale(-1.0F, -1.0F, 1.0F); body.setTransform(stack) .setChanged(); + + // TODO: Use LitVisual if possible. + updateLight(partialTick); } protected void updateContents(TransformedInstance contents, PoseStack stack, float partialTick) { @@ -205,8 +203,8 @@ protected void updateContents(TransformedInstance contents, PoseStack stack, flo .setChanged(); } - public void updateLight() { - relight(entity.blockPosition(), body, contents); + public void updateLight(float partialTick) { + relight(partialTick, body, contents); } @Override diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/ShulkerBoxVisual.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/ShulkerBoxVisual.java index 45b76ba87..5b648c532 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/ShulkerBoxVisual.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/ShulkerBoxVisual.java @@ -34,19 +34,16 @@ public class ShulkerBoxVisual extends AbstractBlockEntityVisual extends MinecartVisual { private static final int WHITE_OVERLAY = OverlayTexture.pack(OverlayTexture.u(1.0F), 10); - public TntMinecartVisual(VisualizationContext ctx, T entity) { - super(ctx, entity, TNT_BODY_MODEL); + public TntMinecartVisual(VisualizationContext ctx, T entity, float partialTick) { + super(ctx, entity, partialTick, TNT_BODY_MODEL); } @Override @@ -35,7 +35,7 @@ protected void updateContents(TransformedInstance contents, PoseStack stack, flo } contents.setTransform(stack) - .setOverlay(overlay) + .overlay(overlay) .setChanged(); } } diff --git a/common/src/main/java/dev/engine_room/flywheel/vanilla/VanillaVisuals.java b/common/src/main/java/dev/engine_room/flywheel/vanilla/VanillaVisuals.java index f39a0a186..fb7bc7a10 100644 --- a/common/src/main/java/dev/engine_room/flywheel/vanilla/VanillaVisuals.java +++ b/common/src/main/java/dev/engine_room/flywheel/vanilla/VanillaVisuals.java @@ -47,27 +47,27 @@ public static void init() { .apply(); builder(EntityType.CHEST_MINECART) - .factory((ctx, entity) -> new MinecartVisual<>(ctx, entity, MinecartVisual.CHEST_BODY_MODEL)) + .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.CHEST_BODY_MODEL)) .skipVanillaRender(MinecartVisual::shouldSkipRender) .apply(); builder(EntityType.COMMAND_BLOCK_MINECART) - .factory((ctx, entity) -> new MinecartVisual<>(ctx, entity, MinecartVisual.COMMAND_BLOCK_BODY_MODEL)) + .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.COMMAND_BLOCK_BODY_MODEL)) .skipVanillaRender(MinecartVisual::shouldSkipRender) .apply(); builder(EntityType.FURNACE_MINECART) - .factory((ctx, entity) -> new MinecartVisual<>(ctx, entity, MinecartVisual.FURNACE_BODY_MODEL)) + .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.FURNACE_BODY_MODEL)) .skipVanillaRender(MinecartVisual::shouldSkipRender) .apply(); builder(EntityType.HOPPER_MINECART) - .factory((ctx, entity) -> new MinecartVisual<>(ctx, entity, MinecartVisual.HOPPER_BODY_MODEL)) + .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.HOPPER_BODY_MODEL)) .skipVanillaRender(MinecartVisual::shouldSkipRender) .apply(); builder(EntityType.MINECART) - .factory((ctx, entity) -> new MinecartVisual<>(ctx, entity, MinecartVisual.STANDARD_BODY_MODEL)) + .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.STANDARD_BODY_MODEL)) .skipVanillaRender(MinecartVisual::shouldSkipRender) .apply(); builder(EntityType.SPAWNER_MINECART) - .factory((ctx, entity) -> new MinecartVisual<>(ctx, entity, MinecartVisual.SPAWNER_BODY_MODEL)) + .factory((ctx, entity, partialTick) -> new MinecartVisual<>(ctx, entity, partialTick, MinecartVisual.SPAWNER_BODY_MODEL)) .skipVanillaRender(MinecartVisual::shouldSkipRender) .apply(); builder(EntityType.TNT_MINECART) diff --git a/common/src/test/java/dev/engine_room/flywheel/lib/util/TestAtomicBitset.java b/common/src/test/java/dev/engine_room/flywheel/lib/util/TestAtomicBitset.java index dd93838ac..a81d719cd 100644 --- a/common/src/test/java/dev/engine_room/flywheel/lib/util/TestAtomicBitset.java +++ b/common/src/test/java/dev/engine_room/flywheel/lib/util/TestAtomicBitset.java @@ -7,9 +7,9 @@ public class TestAtomicBitset { @Test void testNextClearBit() { - var segmentLength = 1 << AtomicBitset.DEFAULT_LOG2_SEGMENT_SIZE_IN_BITS; - var bitLength = 2 << AtomicBitset.DEFAULT_LOG2_SEGMENT_SIZE_IN_BITS; - var bs = new AtomicBitset(AtomicBitset.DEFAULT_LOG2_SEGMENT_SIZE_IN_BITS, bitLength); + var segmentLength = 1 << AtomicBitSet.DEFAULT_LOG2_SEGMENT_SIZE_IN_BITS; + var bitLength = 2 << AtomicBitSet.DEFAULT_LOG2_SEGMENT_SIZE_IN_BITS; + var bs = new AtomicBitSet(AtomicBitSet.DEFAULT_LOG2_SEGMENT_SIZE_IN_BITS, bitLength); Assertions.assertEquals(0, bs.nextClearBit(0)); Assertions.assertEquals(1, bs.nextClearBit(1)); diff --git a/gradle.properties b/gradle.properties index de2db2e5a..35192faf3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,8 @@ neoforge_version_range = [20.4.234,) # General build dependency versions java_version = 17 -arch_loom_version = 1.6-SNAPSHOT +# FIXME: This doesn't do anything. +# arch_loom_version = 1.6-SNAPSHOT parchment_version = 2024.04.14 # Minecraft build dependency versions diff --git a/settings.gradle.kts b/settings.gradle.kts index 5bb943455..97288b494 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -12,10 +12,11 @@ pluginManagement { maven("https://maven.parchmentmc.org") } - plugins { - val arch_loom_version: String by settings - id("dev.architectury.loom") version arch_loom_version - } + // FIXME: This doesn't do anything. The actual version is always the one defined in buildSrc/build.gradle.kts. +// plugins { +// val arch_loom_version: String by settings +// id("dev.architectury.loom") version arch_loom_version +// } } rootProject.name = "Flywheel"