meshes = ImmutableList.builder();
for (MeshEmitter emitter : emitterMap.values()) {
@@ -60,14 +52,4 @@ public SimpleModel end() {
return new SimpleModel(meshes.build());
}
-
- @Nullable
- public BufferBuilder getBuffer(RenderType renderType, boolean shade, boolean ao) {
- Material key = blockMaterialFunction.apply(renderType, shade, ao);
- if (key != null) {
- return emitterMap.get(renderType).getBuffer(key);
- } else {
- return null;
- }
- }
}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java
index c0191fc4c..093fdd332 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/MeshHelper.java
@@ -2,7 +2,7 @@
import java.nio.ByteBuffer;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.lwjgl.system.MemoryUtil;
import com.mojang.blaze3d.vertex.MeshData;
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModel.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModel.java
index 0b80329e9..68c30a8d6 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModel.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModel.java
@@ -1,49 +1,42 @@
package dev.engine_room.flywheel.lib.model.baked;
-import java.util.concurrent.ConcurrentMap;
-
+import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.UnknownNullability;
-import com.google.common.collect.MapMaker;
-
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
+import net.minecraft.client.resources.model.SimpleModelWrapper;
+import net.minecraft.resources.Identifier;
/**
* A helper class for loading and accessing JSON models not directly used by any blocks or items.
- *
- * Creating a PartialModel will make Minecraft automatically load the associated modelLocation.
- *
- * Once Minecraft has finished baking all models, all PartialModels will have their bakedModel fields populated.
+ *
+ * Creating a PartialModel will make Minecraft automatically load the associated modelId and bake the model as a
+ * {@link SimpleModelWrapper}.
+ *
+ *
Once Minecraft has finished baking all models, all PartialModels will have their blockStateModel fields populated.
+ * Newly created PartialModels will contain a null model until the next resource reload is finished.
*/
-public final class PartialModel {
- static final ConcurrentMap ALL = new MapMaker().weakValues().makeMap();
- static boolean populateOnInit = false;
-
- private final ResourceLocation modelLocation;
+@ApiStatus.NonExtendable
+public class PartialModel {
+ final Identifier modelId;
@UnknownNullability
- BakedModel bakedModel;
-
- private PartialModel(ResourceLocation modelLocation) {
- this.modelLocation = modelLocation;
+ BlockStateModel blockStateModel;
- if (populateOnInit) {
- bakedModel = FlwLibXplat.INSTANCE.getBakedModel(Minecraft.getInstance().getModelManager(), modelLocation);
- }
+ PartialModel(Identifier modelId) {
+ this.modelId = modelId;
}
- public static PartialModel of(ResourceLocation modelLocation) {
- return ALL.computeIfAbsent(modelLocation, PartialModel::new);
+ public static PartialModel of(Identifier modelId) {
+ return FlwLibXplat.INSTANCE.createPartialModel(modelId);
}
@UnknownNullability
- public BakedModel get() {
- return bakedModel;
+ public BlockStateModel get() {
+ return blockStateModel;
}
- public ResourceLocation modelLocation() {
- return modelLocation;
+ public Identifier modelId() {
+ return modelId;
}
}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/SinglePosVirtualBlockGetter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/SinglePosVirtualBlockGetter.java
index 21d248724..729ad5565 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/SinglePosVirtualBlockGetter.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/SinglePosVirtualBlockGetter.java
@@ -2,7 +2,7 @@
import java.util.function.ToIntFunction;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.Blocks;
@@ -67,7 +67,7 @@ public int getHeight() {
}
@Override
- public int getMinBuildHeight() {
+ public int getMinY() {
return pos.getY();
}
}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/TransformingVertexConsumer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/TransformingVertexConsumer.java
index 0e8b91380..d8af3dea1 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/TransformingVertexConsumer.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/TransformingVertexConsumer.java
@@ -41,6 +41,12 @@ public VertexConsumer setColor(int red, int green, int blue, int alpha) {
return this;
}
+ @Override
+ public VertexConsumer setColor(int color) {
+ delegate.setColor(color);
+ return this;
+ }
+
@Override
public VertexConsumer setUv(float u, float v) {
delegate.setUv(u, v);
@@ -68,4 +74,10 @@ public VertexConsumer setNormal(float x, float y, float z) {
MatrixMath.transformNormalZ(matrix, x, y, z));
return this;
}
+
+ @Override
+ public VertexConsumer setLineWidth(float width) {
+ delegate.setLineWidth(width);
+ return this;
+ }
}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualBlockGetter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualBlockGetter.java
index 1b5782d43..57dbc9f6a 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualBlockGetter.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualBlockGetter.java
@@ -3,10 +3,10 @@
import java.util.function.ToIntFunction;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.block.BlockAndTintGetter;
import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
import net.minecraft.core.registries.Registries;
-import net.minecraft.world.level.BlockAndTintGetter;
+import net.minecraft.world.level.CardinalLighting;
import net.minecraft.world.level.ColorResolver;
import net.minecraft.world.level.biome.Biome;
import net.minecraft.world.level.biome.Biomes;
@@ -14,6 +14,8 @@
import net.minecraft.world.level.material.FluidState;
public abstract class VirtualBlockGetter implements BlockAndTintGetter {
+ public static final CardinalLighting FULL_LIGHTING = new CardinalLighting(1F, 1F, 1F, 1F, 1F, 1F);
+
protected final VirtualLightEngine lightEngine;
public VirtualBlockGetter(ToIntFunction blockLightFunc, ToIntFunction skyLightFunc) {
@@ -26,8 +28,8 @@ public FluidState getFluidState(BlockPos pos) {
}
@Override
- public float getShade(Direction direction, boolean shaded) {
- return 1f;
+ public CardinalLighting cardinalLighting() {
+ return FULL_LIGHTING;
}
@Override
@@ -37,7 +39,7 @@ public LevelLightEngine getLightEngine() {
@Override
public int getBlockTint(BlockPos pos, ColorResolver resolver) {
- Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().registryOrThrow(Registries.BIOME).getOrThrow(Biomes.PLAINS);
+ Biome plainsBiome = Minecraft.getInstance().getConnection().registryAccess().lookupOrThrow(Registries.BIOME).getValueOrThrow(Biomes.PLAINS);
return resolver.getColor(plainsBiome, pos.getX(), pos.getZ());
}
}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualLightEngine.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualLightEngine.java
index e8b072384..cbb50b53d 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualLightEngine.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/baked/VirtualLightEngine.java
@@ -2,7 +2,7 @@
import java.util.function.ToIntFunction;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java
index 87776ec0b..09d73b94f 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java
@@ -5,7 +5,7 @@
import java.util.function.ObjIntConsumer;
import org.jetbrains.annotations.ApiStatus;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
import org.joml.Quaternionf;
@@ -460,12 +460,12 @@ public PartPose storePose() {
}
public void loadPose(PartPose pose) {
- x = pose.x;
- y = pose.y;
- z = pose.z;
- xRot = pose.xRot;
- yRot = pose.yRot;
- zRot = pose.zRot;
+ x = pose.x();
+ y = pose.y();
+ z = pose.z();
+ xRot = pose.xRot();
+ yRot = pose.yRot();
+ zRot = pose.zRot();
xScale = ModelPart.DEFAULT_SCALE;
yScale = ModelPart.DEFAULT_SCALE;
zScale = ModelPart.DEFAULT_SCALE;
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/MeshTree.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/MeshTree.java
index 3575a4386..e60cc942f 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/MeshTree.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/MeshTree.java
@@ -3,7 +3,7 @@
import java.util.Arrays;
import java.util.NoSuchElementException;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import com.mojang.blaze3d.vertex.PoseStack;
@@ -19,8 +19,8 @@
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.model.geom.PartPose;
-import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.OverlayTexture;
+import net.minecraft.util.LightCoordsUtil;
public final class MeshTree {
private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
@@ -74,7 +74,7 @@ private static Mesh compile(ModelPart modelPart, ThreadLocalObjects objects) {
}
VertexWriter vertexWriter = objects.vertexWriter;
- FlwLibLink.INSTANCE.compileModelPart(modelPart, IDENTITY_POSE, vertexWriter, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0xFFFFFFFF);
+ FlwLibLink.INSTANCE.compileModelPart(modelPart, IDENTITY_POSE, vertexWriter, LightCoordsUtil.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0xFFFFFFFF);
MemoryBlock data = vertexWriter.copyDataAndReset();
VertexView vertexView = new PosTexNormalVertexView();
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTree.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTree.java
index 5774ebf44..57c3cd652 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTree.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTree.java
@@ -4,7 +4,7 @@
import java.util.Map;
import java.util.NoSuchElementException;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.model.Model;
import net.minecraft.client.model.geom.PartPose;
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTrees.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTrees.java
index 1f26053f4..6f9d126ef 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTrees.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/ModelTrees.java
@@ -5,7 +5,7 @@
import java.util.Map;
import java.util.Set;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.material.Material;
import dev.engine_room.flywheel.api.model.Mesh;
@@ -13,12 +13,16 @@
import dev.engine_room.flywheel.lib.model.RetexturedMesh;
import dev.engine_room.flywheel.lib.model.SingleMeshModel;
import dev.engine_room.flywheel.lib.util.RendererReloadCache;
+import net.minecraft.client.Minecraft;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
+import net.minecraft.client.resources.model.sprite.AtlasManager;
+import net.minecraft.client.resources.model.sprite.SpriteId;
public final class ModelTrees {
private static final RendererReloadCache CACHE = new RendererReloadCache<>(k -> {
- ModelTree tree = convert("", MeshTree.of(k.layer), k.pathsToPrune, k.texture != null ? k.texture.sprite() : null, k.material);
+ AtlasManager atlas = Minecraft.getInstance().getAtlasManager();
+ ModelTree tree = convert("", MeshTree.of(k.layer), k.pathsToPrune, k.texture != null ? atlas.get(k.texture) : null, k.material);
if (tree == null) {
throw new IllegalArgumentException("Cannot prune root node!");
@@ -34,7 +38,7 @@ public static ModelTree of(ModelLayerLocation layer, Material material) {
return CACHE.get(new ModelTreeKey(layer, Collections.emptySet(), null, material));
}
- public static ModelTree of(ModelLayerLocation layer, net.minecraft.client.resources.model.Material texture, Material material) {
+ public static ModelTree of(ModelLayerLocation layer, SpriteId texture, Material material) {
return CACHE.get(new ModelTreeKey(layer, Collections.emptySet(), texture, material));
}
@@ -42,7 +46,7 @@ public static ModelTree of(ModelLayerLocation layer, Set pathsToPrune, M
return CACHE.get(new ModelTreeKey(layer, Set.copyOf(pathsToPrune), null, material));
}
- public static ModelTree of(ModelLayerLocation layer, Set pathsToPrune, net.minecraft.client.resources.model.Material texture, Material material) {
+ public static ModelTree of(ModelLayerLocation layer, Set pathsToPrune, SpriteId texture, Material material) {
return CACHE.get(new ModelTreeKey(layer, Set.copyOf(pathsToPrune), texture, material));
}
@@ -78,6 +82,6 @@ private static ModelTree convert(String path, MeshTree meshTree, Set pat
return new ModelTree(model, meshTree.initialPose(), children);
}
- private record ModelTreeKey(ModelLayerLocation layer, Set pathsToPrune, @Nullable net.minecraft.client.resources.model.Material texture, Material material) {
+ private record ModelTreeKey(ModelLayerLocation layer, Set pathsToPrune, @Nullable SpriteId texture, Material material) {
}
}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java
index 00d808ee3..cb526fbc1 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/VertexWriter.java
@@ -48,6 +48,12 @@ public VertexConsumer setColor(int red, int green, int blue, int alpha) {
return this;
}
+ @Override
+ public VertexConsumer setColor(int color) {
+ // ignore color
+ return this;
+ }
+
@Override
public VertexConsumer setUv(float u, float v) {
if (!filledTexture) {
@@ -83,6 +89,12 @@ public VertexConsumer setNormal(float x, float y, float z) {
return this;
}
+ @Override
+ public VertexConsumer setLineWidth(float width) {
+ // ignore line width
+ return this;
+ }
+
private long vertexPtr() {
return data.ptr() + (vertexCount - 1) * STRIDE;
}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/task/functional/package-info.java b/common/src/lib/java/dev/engine_room/flywheel/lib/task/functional/package-info.java
index 54e74141a..32bf7cee2 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/task/functional/package-info.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/task/functional/package-info.java
@@ -5,12 +5,7 @@
* interface, but do not need to create additional closure objects to translate when the consumer wishes to ignore
* the context object.
*/
-@ParametersAreNonnullByDefault
-@FieldsAreNonnullByDefault
-@MethodsReturnNonnullByDefault
+@NullMarked
package dev.engine_room.flywheel.lib.task.functional;
-import javax.annotation.ParametersAreNonnullByDefault;
-
-import net.minecraft.FieldsAreNonnullByDefault;
-import net.minecraft.MethodsReturnNonnullByDefault;
+import org.jspecify.annotations.NullMarked;
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/IdentifierUtil.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/IdentifierUtil.java
new file mode 100644
index 000000000..3a9d0f983
--- /dev/null
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/util/IdentifierUtil.java
@@ -0,0 +1,63 @@
+package dev.engine_room.flywheel.lib.util;
+
+import com.mojang.brigadier.StringReader;
+import com.mojang.brigadier.exceptions.CommandSyntaxException;
+
+import dev.engine_room.flywheel.api.Flywheel;
+import net.minecraft.IdentifierException;
+import net.minecraft.resources.Identifier;
+
+public final class IdentifierUtil {
+ private IdentifierUtil() {
+ }
+
+ public static Identifier id(String path) {
+ return Identifier.fromNamespaceAndPath(Flywheel.ID, path);
+ }
+
+ /**
+ * Same as {@link Identifier#parse(String)}, but defaults to Flywheel namespace.
+ */
+ public static Identifier parseFlywheelDefault(String id) {
+ String namespace = Flywheel.ID;
+ String path = id;
+
+ int i = id.indexOf(Identifier.NAMESPACE_SEPARATOR);
+ if (i >= 0) {
+ path = id.substring(i + 1);
+ if (i >= 1) {
+ namespace = id.substring(0, i);
+ }
+ }
+
+ return Identifier.fromNamespaceAndPath(namespace, path);
+ }
+
+ /**
+ * Same as {@link Identifier#read(StringReader)}, but defaults to Flywheel namespace.
+ */
+ public static Identifier readFlywheelDefault(StringReader reader) throws CommandSyntaxException {
+ int i = reader.getCursor();
+
+ while (reader.canRead() && Identifier.isAllowedInIdentifier(reader.peek())) {
+ reader.skip();
+ }
+
+ String s = reader.getString().substring(i, reader.getCursor());
+
+ try {
+ return parseFlywheelDefault(s);
+ } catch (IdentifierException e) {
+ reader.setCursor(i);
+ throw Identifier.ERROR_INVALID.createWithContext(reader);
+ }
+ }
+
+ /**
+ * Same as {@link Identifier#toDebugFileName()}, but also removes the file extension.
+ */
+ public static String toDebugFileNameNoExtension(Identifier id) {
+ var stringLoc = id.toDebugFileName();
+ return stringLoc.substring(0, stringLoc.lastIndexOf('.'));
+ }
+}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/RecyclingPoseStack.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/RecyclingPoseStack.java
deleted file mode 100644
index fb73e087a..000000000
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/util/RecyclingPoseStack.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package dev.engine_room.flywheel.lib.util;
-
-import java.util.ArrayDeque;
-import java.util.Deque;
-
-import com.mojang.blaze3d.vertex.PoseStack;
-
-import dev.engine_room.flywheel.lib.internal.FlwLibLink;
-
-/**
- * A {@link PoseStack} that recycles {@link PoseStack.Pose} objects.
- *
- * Vanilla's {@link PoseStack} can get quite expensive to use when each game object needs to
- * maintain their own stack. This class helps alleviate memory pressure by making Pose objects
- * long-lived. Note that this means that you CANNOT safely store a Pose object outside
- * the RecyclingPoseStack that created it.
- */
-public class RecyclingPoseStack extends PoseStack {
- private final Deque recycleBin = new ArrayDeque<>();
-
- @Override
- public void pushPose() {
- if (recycleBin.isEmpty()) {
- super.pushPose();
- } else {
- var last = last();
- var recycle = recycleBin.removeLast();
- recycle.pose()
- .set(last.pose());
- recycle.normal()
- .set(last.normal());
- FlwLibLink.INSTANCE.getPoseStack(this)
- .addLast(recycle);
- }
- }
-
- @Override
- public void popPose() {
- recycleBin.addLast(FlwLibLink.INSTANCE.getPoseStack(this)
- .removeLast());
- }
-}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceReloadHolder.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceReloadHolder.java
index 9ff36d40c..1dc6c6003 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceReloadHolder.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceReloadHolder.java
@@ -6,7 +6,7 @@
import java.util.function.Supplier;
import org.jetbrains.annotations.ApiStatus;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
public final class ResourceReloadHolder implements Supplier {
private static final Set> ALL = Collections.newSetFromMap(new WeakHashMap<>());
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceUtil.java b/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceUtil.java
deleted file mode 100644
index b61d9292a..000000000
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/util/ResourceUtil.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package dev.engine_room.flywheel.lib.util;
-
-import com.mojang.brigadier.StringReader;
-import com.mojang.brigadier.exceptions.CommandSyntaxException;
-import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
-
-import dev.engine_room.flywheel.api.Flywheel;
-import net.minecraft.ResourceLocationException;
-import net.minecraft.network.chat.Component;
-import net.minecraft.resources.ResourceLocation;
-
-public final class ResourceUtil {
- private static final SimpleCommandExceptionType ERROR_INVALID = new SimpleCommandExceptionType(Component.translatable("argument.id.invalid"));
-
- private ResourceUtil() {
- }
-
- public static ResourceLocation rl(String path) {
- return ResourceLocation.fromNamespaceAndPath(Flywheel.ID, path);
- }
-
- /**
- * Same as {@link ResourceLocation#parse(String)}, but defaults to Flywheel namespace.
- */
- public static ResourceLocation parseFlywheelDefault(String location) {
- String namespace = Flywheel.ID;
- String path = location;
-
- int i = location.indexOf(ResourceLocation.NAMESPACE_SEPARATOR);
- if (i >= 0) {
- path = location.substring(i + 1);
- if (i >= 1) {
- namespace = location.substring(0, i);
- }
- }
-
- return ResourceLocation.fromNamespaceAndPath(namespace, path);
- }
-
- /**
- * Same as {@link ResourceLocation#read(StringReader)}, but defaults to Flywheel namespace.
- */
- public static ResourceLocation readFlywheelDefault(StringReader reader) throws CommandSyntaxException {
- int i = reader.getCursor();
-
- while (reader.canRead() && ResourceLocation.isAllowedInResourceLocation(reader.peek())) {
- reader.skip();
- }
-
- String s = reader.getString().substring(i, reader.getCursor());
-
- try {
- return parseFlywheelDefault(s);
- } catch (ResourceLocationException resourcelocationexception) {
- reader.setCursor(i);
- throw ERROR_INVALID.createWithContext(reader);
- }
- }
-
- /**
- * Same as {@link ResourceLocation#toDebugFileName()}, but also removes the file extension.
- */
- public static String toDebugFileNameNoExtension(ResourceLocation resourceLocation) {
- var stringLoc = resourceLocation.toDebugFileName();
- return stringLoc.substring(0, stringLoc.lastIndexOf('.'));
- }
-}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java
index 7a7b506f3..2a18b0333 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/AbstractVertexView.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.lib.vertex;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
public abstract class AbstractVertexView implements VertexView {
protected long ptr;
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/FlywheelVertexFormats.java b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/FlywheelVertexFormats.java
new file mode 100644
index 000000000..6459664e4
--- /dev/null
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/FlywheelVertexFormats.java
@@ -0,0 +1,17 @@
+package dev.engine_room.flywheel.lib.vertex;
+
+import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+import com.mojang.blaze3d.vertex.VertexFormat;
+import com.mojang.blaze3d.vertex.VertexFormatElement;
+
+public class FlywheelVertexFormats {
+ /// Basically the same as {@link DefaultVertexFormat#BLOCK} but with the normals included
+ public static final VertexFormat BLOCK_VERTEX_FORMAT = VertexFormat.builder()
+ .add("Position", VertexFormatElement.POSITION)
+ .add("Color",VertexFormatElement.COLOR)
+ .add("UV0",VertexFormatElement.UV0)
+ .add("UV2",VertexFormatElement.UV2)
+ .add("Normal", VertexFormatElement.NORMAL)
+ .padding(1)
+ .build();
+}
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java
index 4c60462a2..a220d6a9c 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/vertex/VertexView.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.lib.vertex;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.lwjgl.system.MemoryUtil;
import dev.engine_room.flywheel.api.vertex.MutableVertexList;
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 25d05d481..1bd92114a 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
@@ -2,7 +2,7 @@
import java.util.Iterator;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.jetbrains.annotations.UnknownNullability;
import org.joml.FrustumIntersection;
@@ -96,15 +96,15 @@ public boolean isVisible(FrustumIntersection frustum) {
*/
public boolean doDistanceLimitThisFrame(DynamicVisual.Context context) {
return !context.limiter()
- .shouldUpdate(pos.distToCenterSqr(context.camera().getPosition()));
+ .shouldUpdate(pos.distToCenterSqr(context.cameraRenderState().pos));
}
protected int computePackedLight() {
- return LevelRenderer.getLightColor(level, pos);
+ return LevelRenderer.getLightCoords(level, pos);
}
protected void relight(BlockPos pos, @Nullable FlatLit... instances) {
- FlatLit.relight(LevelRenderer.getLightColor(level, pos), instances);
+ FlatLit.relight(LevelRenderer.getLightCoords(level, pos), instances);
}
protected void relight(@Nullable FlatLit... instances) {
@@ -112,7 +112,7 @@ protected void relight(@Nullable FlatLit... instances) {
}
protected void relight(BlockPos pos, Iterator<@Nullable FlatLit> instances) {
- FlatLit.relight(LevelRenderer.getLightColor(level, pos), instances);
+ FlatLit.relight(LevelRenderer.getLightCoords(level, pos), instances);
}
protected void relight(Iterator<@Nullable FlatLit> instances) {
@@ -120,7 +120,7 @@ protected void relight(Iterator<@Nullable FlatLit> instances) {
}
protected void relight(BlockPos pos, Iterable<@Nullable FlatLit> instances) {
- FlatLit.relight(LevelRenderer.getLightColor(level, pos), instances);
+ FlatLit.relight(LevelRenderer.getLightCoords(level, pos), instances);
}
protected void relight(Iterable<@Nullable FlatLit> 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 80ffa73a0..3061b2d14 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
@@ -1,8 +1,8 @@
package dev.engine_room.flywheel.lib.visual;
-import org.jetbrains.annotations.Nullable;
import org.joml.FrustumIntersection;
import org.joml.Vector3f;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visual.EntityVisual;
@@ -12,8 +12,9 @@
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 dev.engine_room.flywheel.lib.internal.FlwLibLink;
import net.minecraft.core.BlockPos;
+import net.minecraft.util.LightCoordsUtil;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.LightLayer;
@@ -89,14 +90,14 @@ public Vector3f getVisualPosition(float partialTick) {
}
public boolean isVisible(FrustumIntersection frustum) {
- return entity.noCulling || visibilityTester.check(frustum);
+ return !FlwLibLink.INSTANCE.affectedByCulling(entity) || visibilityTester.check(frustum);
}
protected int computePackedLight(float partialTick) {
BlockPos pos = BlockPos.containing(entity.getLightProbePosition(partialTick));
int blockLight = entity.isOnFire() ? 15 : level.getBrightness(LightLayer.BLOCK, pos);
int skyLight = level.getBrightness(LightLayer.SKY, pos);
- return LightTexture.pack(blockLight, skyLight);
+ return LightCoordsUtil.pack(blockLight, skyLight);
}
protected void relight(float partialTick, @Nullable FlatLit... instances) {
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/EntityVisibilityTester.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/EntityVisibilityTester.java
index 90e2e977e..095b98e24 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/EntityVisibilityTester.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/EntityVisibilityTester.java
@@ -1,8 +1,9 @@
package dev.engine_room.flywheel.lib.visual;
-import org.jetbrains.annotations.Nullable;
import org.joml.FrustumIntersection;
+import org.jspecify.annotations.Nullable;
+import dev.engine_room.flywheel.lib.internal.FlwLibLink;
import dev.engine_room.flywheel.lib.math.MoreMath;
import net.minecraft.core.Vec3i;
import net.minecraft.util.Mth;
@@ -42,7 +43,7 @@ public EntityVisibilityTester(Entity entity, Vec3i renderOrigin, float scale) {
* @return {@code true} if the Entity is visible, {@code false} otherwise.
*/
public boolean check(FrustumIntersection frustum) {
- AABB aabb = entity.getBoundingBoxForCulling();
+ AABB aabb = FlwLibLink.INSTANCE.getBoundingBoxForCulling(entity);
// If we've never seen the entity before assume its visible.
// Fixes entities freezing when they first spawn.
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/FireComponent.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/FireComponent.java
index deb180e8a..9be814e00 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/FireComponent.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/FireComponent.java
@@ -19,9 +19,11 @@
import dev.engine_room.flywheel.lib.model.SingleMeshModel;
import dev.engine_room.flywheel.lib.util.RendererReloadCache;
import dev.engine_room.flywheel.lib.visual.util.SmartRecycler;
-import net.minecraft.client.renderer.LightTexture;
+import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.ModelBakery;
+import net.minecraft.client.resources.model.sprite.SpriteId;
+import net.minecraft.util.LightCoordsUtil;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@@ -33,11 +35,9 @@ public final class FireComponent implements EntityComponent {
.backfaceCulling(false) // Disable backface because we want to be able to flip the model.
.build();
- // Parameterize by the material instead of the sprite
- // because Material#sprite is a surprisingly heavy operation
- // and because sprites are invalidated after a resource reload.
- private static final RendererReloadCache FIRE_MODELS = new RendererReloadCache<>(texture -> {
- return new SingleMeshModel(new FireMesh(texture.sprite()), FIRE_MATERIAL);
+ private static final RendererReloadCache FIRE_MODELS = new RendererReloadCache<>(texture -> {
+ TextureAtlasSprite sprite = Minecraft.getInstance().getAtlasManager().get(texture);
+ return new SingleMeshModel(new FireMesh(sprite), FIRE_MATERIAL);
});
private final VisualizationContext context;
@@ -57,7 +57,7 @@ private TransformedInstance createInstance(Model model) {
TransformedInstance instance = context.instancerProvider()
.instancer(InstanceTypes.TRANSFORMED, model)
.createInstance();
- instance.light(LightTexture.FULL_BLOCK);
+ instance.light(LightCoordsUtil.pack(15, 0));
instance.setChanged();
return instance;
}
@@ -94,8 +94,7 @@ private void setupInstances(DynamicVisual.Context context) {
stack.setIdentity();
stack.translate(entityX - renderOrigin.getX(), entityY - renderOrigin.getY(), entityZ - renderOrigin.getZ());
stack.scale(scale, scale, scale);
- stack.mulPose(Axis.YP.rotationDegrees(-context.camera()
- .getYRot()));
+ stack.mulPose(Axis.YP.rotationDegrees(-context.cameraRenderState().yRot));
stack.translate(0.0F, 0.0F, -0.3F + (float) ((int) maxHeight) * 0.02F);
for (int i = 0; y < maxHeight; ++i) {
@@ -155,7 +154,7 @@ private static void writeVertex(MutableVertexList vertexList, int i, float x, fl
vertexList.b(i, 1);
vertexList.u(i, u);
vertexList.v(i, v);
- vertexList.light(i, LightTexture.FULL_BLOCK);
+ vertexList.light(i, LightCoordsUtil.pack(15, 0));
vertexList.normalX(i, 0);
vertexList.normalY(i, 1);
vertexList.normalZ(i, 0);
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 d4d7ce8eb..87e4ccb83 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
@@ -10,11 +10,13 @@
import dev.engine_room.flywheel.lib.model.LineModelBuilder;
import dev.engine_room.flywheel.lib.visual.util.SmartRecycler;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.LightTexture;
+import net.minecraft.client.gui.components.debug.DebugScreenEntries;
+import net.minecraft.util.LightCoordsUtil;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
+// TODO 1.21.11: vanilla changed hitbox rendering and moved it to the debug renderer system (EntityHitboxDebugRenderer)
public final class HitboxComponent implements EntityComponent {
// 010------110
// /| /|
@@ -67,7 +69,7 @@ private TransformedInstance createInstance(Model model) {
TransformedInstance instance = context.instancerProvider()
.instancer(InstanceTypes.TRANSFORMED, model)
.createInstance();
- instance.light(LightTexture.FULL_BLOCK);
+ instance.light(LightCoordsUtil.pack(15, 0));
instance.setChanged();
return instance;
}
@@ -86,8 +88,8 @@ public void beginFrame(DynamicVisual.Context context) {
recycler.resetCount();
var shouldRenderHitBoxes = Minecraft.getInstance()
- .getEntityRenderDispatcher()
- .shouldRenderHitBoxes();
+ .debugEntries
+ .isCurrentlyEnabled(DebugScreenEntries.ENTITY_HITBOXES);
if (shouldRenderHitBoxes && !entity.isInvisible() && !Minecraft.getInstance()
.showOnlyReducedInfo()) {
float partialTick = context.partialTick();
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/ShadowComponent.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/ShadowComponent.java
index 2af41581f..2a86de5ec 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/ShadowComponent.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visual/component/ShadowComponent.java
@@ -1,8 +1,8 @@
package dev.engine_room.flywheel.lib.visual.component;
-import org.jetbrains.annotations.Nullable;
import org.joml.Vector4f;
import org.joml.Vector4fc;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.material.Material;
import dev.engine_room.flywheel.api.material.Transparency;
@@ -18,12 +18,13 @@
import dev.engine_room.flywheel.lib.model.SingleMeshModel;
import dev.engine_room.flywheel.lib.visual.util.InstanceRecycler;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.LightTexture;
+import net.minecraft.client.renderer.Lightmap;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Direction.Axis;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.resources.Identifier;
+import net.minecraft.util.LightCoordsUtil;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
@@ -42,7 +43,7 @@
* The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.
*/
public final class ShadowComponent implements EntityComponent {
- private static final ResourceLocation SHADOW_TEXTURE = ResourceLocation.withDefaultNamespace("textures/misc/shadow.png");
+ private static final Identifier SHADOW_TEXTURE = Identifier.withDefaultNamespace("textures/misc/shadow.png");
private static final Material SHADOW_MATERIAL = SimpleMaterial.builder()
.texture(SHADOW_TEXTURE)
.mipmap(false)
@@ -157,7 +158,7 @@ private void setupInstance(ChunkAccess chunk, MutableBlockPos pos, float entityX
// Too dark to render.
return;
}
- float blockBrightness = LightTexture.getBrightness(level.dimensionType(), maxLocalRawBrightness);
+ float blockBrightness = Lightmap.getBrightness(level.dimensionType(), maxLocalRawBrightness);
float alpha = strength * 0.5F * blockBrightness;
if (alpha < 0.0F) {
// Too far away/too weak to render.
@@ -256,7 +257,7 @@ private static void writeVertex(MutableVertexList vertexList, int i, float x, fl
vertexList.b(i, 1);
vertexList.u(i, 0);
vertexList.v(i, 0);
- vertexList.light(i, LightTexture.FULL_BRIGHT);
+ vertexList.light(i, LightCoordsUtil.FULL_BRIGHT);
vertexList.overlay(i, OverlayTexture.NO_OVERLAY);
vertexList.normalX(i, 0);
vertexList.normalY(i, 1);
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleBlockEntityVisualizer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleBlockEntityVisualizer.java
index 6a82041aa..e4d393025 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleBlockEntityVisualizer.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleBlockEntityVisualizer.java
@@ -3,7 +3,7 @@
import java.util.Objects;
import java.util.function.Predicate;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visual.BlockEntityVisual;
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleEntityVisualizer.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleEntityVisualizer.java
index 86e1832ea..c817c4a62 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleEntityVisualizer.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/SimpleEntityVisualizer.java
@@ -3,7 +3,7 @@
import java.util.Objects;
import java.util.function.Predicate;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visual.EntityVisual;
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/VisualizationHelper.java b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/VisualizationHelper.java
index 8b8f79860..da7796960 100644
--- a/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/VisualizationHelper.java
+++ b/common/src/lib/java/dev/engine_room/flywheel/lib/visualization/VisualizationHelper.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.lib.visualization;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visual.Effect;
import dev.engine_room.flywheel.api.visual.Visual;
diff --git a/common/src/lib/resources/assets/flywheel/flywheel/fog/linear.glsl b/common/src/lib/resources/assets/flywheel/flywheel/fog/linear.glsl
index 9c03c6791..6411e5953 100644
--- a/common/src/lib/resources/assets/flywheel/flywheel/fog/linear.glsl
+++ b/common/src/lib/resources/assets/flywheel/flywheel/fog/linear.glsl
@@ -1,12 +1,22 @@
-vec4 linearFog(vec4 color, float distance, float fogStart, float fogEnd, vec4 fogColor) {
- if (distance <= fogStart) {
- return color;
+float linearFogValue(float vertexDistance, float fogStart, float fogEnd) {
+ if (vertexDistance <= fogStart) {
+ return 0.0;
+ } else if (vertexDistance >= fogEnd) {
+ return 1.0;
}
- float fogValue = distance < fogEnd ? smoothstep(fogStart, fogEnd, distance) : 1.0;
+ return (vertexDistance - fogStart) / (fogEnd - fogStart);
+}
+
+float totalFogValue(float sphericalVertexDistance, float cylindricalVertexDistance, float environmentalStart, float environmantalEnd, float renderDistanceStart, float renderDistanceEnd) {
+ return max(linearFogValue(sphericalVertexDistance, environmentalStart, environmantalEnd), linearFogValue(cylindricalVertexDistance, renderDistanceStart, renderDistanceEnd));
+}
+
+vec4 linearFog(vec4 color, float sphericalVertexDistance, float cylindricalVertexDistance, float environmentalStart, float environmantalEnd, float renderDistanceStart, float renderDistanceEnd, vec4 fogColor) {
+ float fogValue = totalFogValue(sphericalVertexDistance, cylindricalVertexDistance, environmentalStart, environmantalEnd, renderDistanceStart, renderDistanceEnd);
return vec4(mix(color.rgb, fogColor.rgb, fogValue * fogColor.a), color.a);
}
vec4 flw_fogFilter(vec4 color) {
- return linearFog(color, flw_distance, flw_fogRange.x, flw_fogRange.y, flw_fogColor);
+ return linearFog(color, flw_sphericalDistance, flw_cylindricalDistance, flw_fogEnvironmentalStart, flw_fogEnvironmentalEnd, flw_fogRenderDistanceStart, flw_fogRenderDistanceEnd, flw_fogColor);
}
diff --git a/common/src/lib/resources/assets/flywheel/flywheel/fog/linear_fade.glsl b/common/src/lib/resources/assets/flywheel/flywheel/fog/linear_fade.glsl
index 6eaffb176..f73736aac 100644
--- a/common/src/lib/resources/assets/flywheel/flywheel/fog/linear_fade.glsl
+++ b/common/src/lib/resources/assets/flywheel/flywheel/fog/linear_fade.glsl
@@ -1,13 +1,11 @@
-vec4 linearFogFade(vec4 color, float distance, float fogStart, float fogEnd) {
- if (distance <= fogStart) {
- return color;
- } else if (distance >= fogEnd) {
- return vec4(0.0);
- }
+vec4 linearFogFade(vec4 color, float sphericalVertexDistance, float cylindricalVertexDistance, float environmentalStart, float environmentalEnd, float renderDistanceStart, float renderDistanceEnd) {
+ float sphericalValue = smoothstep(environmentalEnd, environmentalStart, sphericalVertexDistance);
+ float cylindricalValue = smoothstep(renderDistanceEnd, renderDistanceStart, cylindricalVertexDistance);
+ float fadeValue = min(sphericalValue, cylindricalValue);
- return color * smoothstep(fogEnd, fogStart, distance);
+ return color * fadeValue;
}
vec4 flw_fogFilter(vec4 color) {
- return linearFogFade(color, flw_distance, flw_fogRange.x, flw_fogRange.y);
+ return linearFogFade(color, flw_sphericalDistance, flw_cylindricalDistance, flw_fogEnvironmentalStart, flw_fogEnvironmentalEnd, flw_fogRenderDistanceStart, flw_fogRenderDistanceEnd);
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java b/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java
index 1ef3235fc..53efd9370 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java
@@ -14,11 +14,11 @@
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import dev.engine_room.flywheel.api.backend.Backend;
-import dev.engine_room.flywheel.lib.util.ResourceUtil;
+import dev.engine_room.flywheel.lib.util.IdentifierUtil;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.commands.synchronization.SingletonArgumentInfo;
import net.minecraft.network.chat.Component;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.resources.Identifier;
public class BackendArgument implements ArgumentType {
private static final List EXAMPLES = List.of("off", "flywheel:off", "instancing");
@@ -32,7 +32,7 @@ public class BackendArgument implements ArgumentType {
@Override
public Backend parse(StringReader reader) throws CommandSyntaxException {
- ResourceLocation id = ResourceUtil.readFlywheelDefault(reader);
+ Identifier id = IdentifierUtil.readFlywheelDefault(reader);
Backend backend = Backend.REGISTRY.get(id);
if (backend == null) {
@@ -45,7 +45,7 @@ public Backend parse(StringReader reader) throws CommandSyntaxException {
@Override
public CompletableFuture listSuggestions(CommandContext context, SuggestionsBuilder builder) {
String input = builder.getRemaining().toLowerCase(Locale.ROOT);
- for (ResourceLocation id : Backend.REGISTRY.getAllIds()) {
+ for (Identifier id : Backend.REGISTRY.getAllIds()) {
String idStr = id.toString();
if (SharedSuggestionProvider.matchesSubStr(input, idStr) || SharedSuggestionProvider.matchesSubStr(input, id.getPath())) {
builder.suggest(idStr);
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java
index df4262e5a..1f968c689 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java
@@ -5,9 +5,9 @@
import dev.engine_room.flywheel.api.backend.Backend;
import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl;
import dev.engine_room.flywheel.lib.backend.SimpleBackend;
-import dev.engine_room.flywheel.lib.util.ResourceUtil;
+import dev.engine_room.flywheel.lib.util.IdentifierUtil;
import net.minecraft.client.multiplayer.ClientLevel;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.resources.Identifier;
public final class BackendManagerImpl {
public static final Backend OFF_BACKEND = SimpleBackend.builder()
@@ -15,7 +15,7 @@ public final class BackendManagerImpl {
throw new UnsupportedOperationException("Cannot create engine when backend is off.");
})
.supported(() -> true)
- .register(ResourceUtil.rl("off"));
+ .register(IdentifierUtil.id("off"));
private static Backend backend = OFF_BACKEND;
@@ -75,7 +75,7 @@ private static void chooseBackend() {
}
public static String getBackendString() {
- ResourceLocation backendId = Backend.REGISTRY.getId(backend);
+ Identifier backendId = Backend.REGISTRY.getId(backend);
if (backendId == null) {
return "[unregistered]";
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java
index 6f03a7dab..8b5902314 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/FlwApiLinkImpl.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.backend.Backend;
import dev.engine_room.flywheel.api.internal.FlwApiLink;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/FlwDebugInfo.java b/common/src/main/java/dev/engine_room/flywheel/impl/FlwDebugInfo.java
index 438a42038..bd5eaf061 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/FlwDebugInfo.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/FlwDebugInfo.java
@@ -1,8 +1,9 @@
package dev.engine_room.flywheel.impl;
-import java.util.List;
+import java.net.URI;
+import java.util.Locale;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.backend.engine.AbstractInstancer;
@@ -10,17 +11,24 @@
import dev.engine_room.flywheel.backend.gl.GlCompat;
import dev.engine_room.flywheel.impl.visualization.VisualizationManagerImpl;
import dev.engine_room.flywheel.lib.memory.FlwMemoryTracker;
+import dev.engine_room.flywheel.lib.util.IdentifierUtil;
import dev.engine_room.flywheel.lib.util.StringUtil;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntComparators;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.components.debug.DebugScreenDisplayer;
+import net.minecraft.client.gui.components.debug.DebugScreenEntry;
import net.minecraft.core.Vec3i;
-import net.minecraft.network.chat.ClickEvent;
+import net.minecraft.network.chat.ClickEvent.CopyToClipboard;
+import net.minecraft.network.chat.ClickEvent.OpenUrl;
import net.minecraft.network.chat.Component;
-import net.minecraft.network.chat.HoverEvent;
+import net.minecraft.network.chat.HoverEvent.ShowText;
import net.minecraft.network.chat.Style;
+import net.minecraft.resources.Identifier;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.chunk.LevelChunk;
public final class FlwDebugInfo {
@@ -66,13 +74,13 @@ public static Component getDebugCommandInfo() {
return Component.literal(debugInfoString)
.append(Component.literal("\n\nClick to copy debug info to clipboard")
.withStyle(Style.EMPTY.withUnderlined(true)
- .withClickEvent(new ClickEvent(ClickEvent.Action.COPY_TO_CLIPBOARD, debugInfoString))
- .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal(debugInfoString)))))
+ .withClickEvent(new CopyToClipboard(debugInfoString))
+ .withHoverEvent(new ShowText(Component.literal(debugInfoString)))))
.append(Component.literal("\n\nClick to open an issue on GitHub")
.withStyle(Style.EMPTY.withUnderlined(true)
.withColor(ChatFormatting.BLUE)
- .withClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://github.com/Engine-Room/Flywheel/issues"))
- .withHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, Component.literal("Opens URL:\nhttps://github.com/Engine-Room/Flywheel/issues")))));
+ .withClickEvent(new OpenUrl(URI.create("https://github.com/Engine-Room/Flywheel/issues")))
+ .withHoverEvent(new ShowText(Component.literal("Opens URL:\nhttps://github.com/Engine-Room/Flywheel/issues")))));
}
@@ -247,25 +255,46 @@ private static void addOpenGLDebugInfo(StringBuilder out) {
appendLine(out, "Shading Language Version: ").append(GlCompat.GL_SHADING_LANGUAGE_VERSION_STRING);
}
- public static void addDebugInfo(Minecraft minecraft, List systemInfo) {
- if (minecraft.showOnlyReducedInfo()) {
- return;
+ public static class FlwDebugEntry implements DebugScreenEntry {
+ public static final Identifier ID = IdentifierUtil.id("flw_debug_info");
+ private static final Identifier GROUP = IdentifierUtil.id("flywheel");
+
+ @Override
+ public void display(DebugScreenDisplayer displayer, @Nullable Level serverOrClientLevel, @Nullable LevelChunk clientChunk, @Nullable LevelChunk serverChunk) {
+ add(displayer, "Flywheel: %s", FlwImplXplat.INSTANCE.getVersionStr());
+ add(displayer, "Backend: %s", BackendManagerImpl.getBackendString());
+ add(displayer, "Update limiting: %s", FlwConfig.INSTANCE.limitUpdates() ? "on" : "off");
+
+ Level clientLevel = clientChunk != null ? clientChunk.getLevel() : null;
+ VisualizationManager manager = VisualizationManager.get(clientLevel);
+ if (manager != null) {
+ add(displayer, "B: %s, E: %s, F: %s",
+ manager.blockEntities().visualCount(),
+ manager.entities().visualCount(),
+ manager.effects().visualCount()
+ );
+
+ Vec3i renderOrigin = manager.renderOrigin();
+ add(displayer, "Origin: %s, %s, %s",
+ renderOrigin.getX(),
+ renderOrigin.getY(),
+ renderOrigin.getZ()
+ );
+ }
+
+ add(displayer, "Memory Usage: CPU: %s, GPU: %s",
+ StringUtil.formatBytes(FlwMemoryTracker.getCpuMemory()),
+ StringUtil.formatBytes(FlwMemoryTracker.getGpuMemory())
+ );
}
- systemInfo.add("");
- systemInfo.add("Flywheel: " + FlwImplXplat.INSTANCE.getVersionStr());
- systemInfo.add("Backend: " + BackendManagerImpl.getBackendString());
- systemInfo.add("Update limiting: " + (FlwConfig.INSTANCE.limitUpdates() ? "on" : "off"));
-
- VisualizationManager manager = VisualizationManager.get(minecraft.level);
- if (manager != null) {
- systemInfo.add("B: " + manager.blockEntities().visualCount()
- + ", E: " + manager.entities().visualCount()
- + ", F: " + manager.effects().visualCount());
- Vec3i renderOrigin = manager.renderOrigin();
- systemInfo.add("Origin: " + renderOrigin.getX() + ", " + renderOrigin.getY() + ", " + renderOrigin.getZ());
+ @Override
+ public boolean isAllowed(boolean reducedDebugInfo) {
+ return true;
}
- systemInfo.add("Memory Usage: CPU: " + StringUtil.formatBytes(FlwMemoryTracker.getCpuMemory()) + ", GPU: " + StringUtil.formatBytes(FlwMemoryTracker.getGpuMemory()));
+ private static void add(DebugScreenDisplayer displayer, String input, Object... args) {
+ displayer.addToGroup(GROUP, String.format(Locale.ROOT, input, args));
+ }
}
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/FlwLibLinkImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/FlwLibLinkImpl.java
index 10244b19c..f392720d5 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/FlwLibLinkImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/FlwLibLinkImpl.java
@@ -1,6 +1,5 @@
package dev.engine_room.flywheel.impl;
-import java.util.Deque;
import java.util.Map;
import org.slf4j.Logger;
@@ -11,11 +10,15 @@
import dev.engine_room.flywheel.impl.compat.IrisCompat;
import dev.engine_room.flywheel.impl.compat.OptifineCompat;
import dev.engine_room.flywheel.impl.extension.PoseStackExtension;
+import dev.engine_room.flywheel.impl.mixin.EntityRendererAccessor;
import dev.engine_room.flywheel.impl.mixin.ModelPartAccessor;
-import dev.engine_room.flywheel.impl.mixin.PoseStackAccessor;
import dev.engine_room.flywheel.lib.internal.FlwLibLink;
import dev.engine_room.flywheel.lib.transform.PoseTransformStack;
+import net.minecraft.client.Minecraft;
import net.minecraft.client.model.geom.ModelPart;
+import net.minecraft.client.renderer.entity.EntityRenderer;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.phys.AABB;
public class FlwLibLinkImpl implements FlwLibLink {
@Override
@@ -39,8 +42,19 @@ public void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer
}
@Override
- public Deque getPoseStack(PoseStack stack) {
- return ((PoseStackAccessor) stack).flywheel$getPoseStack();
+ public boolean affectedByCulling(T entity) {
+ EntityRenderer super T, ?> renderer = Minecraft.getInstance()
+ .getEntityRenderDispatcher()
+ .getRenderer(entity);
+ return ((EntityRendererAccessor) renderer).flywheel$affectedByCulling(entity);
+ }
+
+ @Override
+ public AABB getBoundingBoxForCulling(T entity) {
+ EntityRenderer super T, ?> renderer = Minecraft.getInstance()
+ .getEntityRenderDispatcher()
+ .getRenderer(entity);
+ return ((EntityRendererAccessor) renderer).flywheel$getBoundingBoxForCulling(entity);
}
@Override
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/compat/CompatMod.java b/common/src/main/java/dev/engine_room/flywheel/impl/compat/CompatMod.java
index 8217cb963..c53fa9ecd 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/compat/CompatMod.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/compat/CompatMod.java
@@ -3,7 +3,6 @@
import dev.engine_room.flywheel.impl.FlwImplXplat;
public enum CompatMod {
- EMBEDDIUM("embeddium"),
IRIS("iris"),
SODIUM("sodium");
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/compat/OptifineCompat.java b/common/src/main/java/dev/engine_room/flywheel/impl/compat/OptifineCompat.java
index 42dfe4687..4d14fd4ab 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/compat/OptifineCompat.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/compat/OptifineCompat.java
@@ -2,7 +2,7 @@
import java.lang.reflect.Field;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.impl.FlwImpl;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java b/common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java
index 130272c43..32cccd7f9 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/compat/SodiumCompat.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl.compat;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
import dev.engine_room.flywheel.impl.FlwImpl;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/event/RenderContextImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/event/RenderContextImpl.java
index 5b52009d5..c2748a363 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/event/RenderContextImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/event/RenderContextImpl.java
@@ -4,18 +4,21 @@
import org.joml.Matrix4fc;
import dev.engine_room.flywheel.api.backend.RenderContext;
-import net.minecraft.client.Camera;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
import net.minecraft.client.renderer.RenderBuffers;
+import net.minecraft.client.renderer.state.level.CameraRenderState;
+import net.minecraft.client.renderer.state.level.LevelRenderState;
public record RenderContextImpl(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView,
- Matrix4fc projection, Matrix4fc viewProjection, Camera camera,
- float partialTick) implements RenderContext {
- public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView, Matrix4f projection, Camera camera, float partialTick) {
+ Matrix4fc projection, Matrix4fc viewProjection, CameraRenderState cameraRenderState,
+ LevelRenderState levelRenderState, float partialTick) implements RenderContext {
+ public static ScopedValue PROJECTION_MATRIX_NO_BOB = ScopedValue.newInstance();
+
+ public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView, Matrix4f projection, CameraRenderState cameraRenderState, LevelRenderState levelRenderState, float partialTick) {
Matrix4f viewProjection = new Matrix4f(projection);
viewProjection.mul(modelView);
- return new RenderContextImpl(renderer, level, buffers, modelView, projection, viewProjection, camera, partialTick);
+ return new RenderContextImpl(renderer, level, buffers, modelView, projection, viewProjection, cameraRenderState, levelRenderState, partialTick);
}
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/extension/BlockEntityTypeExtension.java b/common/src/main/java/dev/engine_room/flywheel/impl/extension/BlockEntityTypeExtension.java
index b15f29c7a..93541d0c6 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/extension/BlockEntityTypeExtension.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/extension/BlockEntityTypeExtension.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl.extension;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
import net.minecraft.world.level.block.entity.BlockEntity;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/extension/EntityTypeExtension.java b/common/src/main/java/dev/engine_room/flywheel/impl/extension/EntityTypeExtension.java
index 2b0f8927f..5aa6cc4da 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/extension/EntityTypeExtension.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/extension/EntityTypeExtension.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl.extension;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
import net.minecraft.world.entity.Entity;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/layout/LayoutBuilderImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/layout/LayoutBuilderImpl.java
index fbd2f8178..4472fee51 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/layout/LayoutBuilderImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/layout/LayoutBuilderImpl.java
@@ -5,7 +5,7 @@
import java.util.Locale;
import java.util.Set;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.jetbrains.annotations.Range;
import dev.engine_room.flywheel.api.layout.ElementType;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java
index c429dae95..90c879844 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/BlockEntityTypeMixin.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl.mixin;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityRendererAccessor.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityRendererAccessor.java
new file mode 100644
index 000000000..2c4ad5a05
--- /dev/null
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityRendererAccessor.java
@@ -0,0 +1,17 @@
+package dev.engine_room.flywheel.impl.mixin;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+import net.minecraft.client.renderer.entity.EntityRenderer;
+import net.minecraft.world.entity.Entity;
+import net.minecraft.world.phys.AABB;
+
+@Mixin(EntityRenderer.class)
+public interface EntityRendererAccessor {
+ @Invoker("affectedByCulling")
+ boolean flywheel$affectedByCulling(T entity);
+
+ @Invoker("getBoundingBoxForCulling")
+ AABB flywheel$getBoundingBoxForCulling(T entity);
+}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityTypeMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityTypeMixin.java
index 91676872f..5d220ee7e 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityTypeMixin.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/EntityTypeMixin.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl.mixin;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/GameRendererMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/GameRendererMixin.java
new file mode 100644
index 000000000..675a5aedd
--- /dev/null
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/GameRendererMixin.java
@@ -0,0 +1,29 @@
+package dev.engine_room.flywheel.impl.mixin;
+
+import org.joml.Matrix4f;
+import org.joml.Matrix4fc;
+import org.joml.Vector4f;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
+import com.mojang.blaze3d.buffers.GpuBufferSlice;
+import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
+
+import dev.engine_room.flywheel.impl.event.RenderContextImpl;
+import net.minecraft.client.DeltaTracker;
+import net.minecraft.client.renderer.GameRenderer;
+import net.minecraft.client.renderer.LevelRenderer;
+import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
+import net.minecraft.client.renderer.state.level.CameraRenderState;
+
+@Mixin(GameRenderer.class)
+public class GameRendererMixin {
+ @WrapOperation(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;renderLevel(Lcom/mojang/blaze3d/resource/GraphicsResourceAllocator;Lnet/minecraft/client/DeltaTracker;ZLnet/minecraft/client/renderer/state/level/CameraRenderState;Lorg/joml/Matrix4fc;Lcom/mojang/blaze3d/buffers/GpuBufferSlice;Lorg/joml/Vector4f;ZLnet/minecraft/client/renderer/chunk/ChunkSectionsToRender;)V"))
+ private void extractProjectionMatrixNoBob(LevelRenderer instance, GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, ChunkSectionsToRender chunkSectionsToRender, Operation original, @Local(name = "projectionMatrix") Matrix4f projectionMatrix) {
+ ScopedValue.where(RenderContextImpl.PROJECTION_MATRIX_NO_BOB, projectionMatrix)
+ .run(() -> original.call(instance, resourceAllocator, deltaTracker, renderOutline, cameraState, modelViewMatrix, terrainFog, fogColor, shouldRenderSky, chunkSectionsToRender));
+ }
+}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/LevelRendererMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/LevelRendererMixin.java
index 8fcccfdf6..c9440d6b4 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/LevelRendererMixin.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/LevelRendererMixin.java
@@ -1,9 +1,12 @@
package dev.engine_room.flywheel.impl.mixin;
+import java.util.Iterator;
import java.util.SortedSet;
-import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
+import org.joml.Matrix4fc;
+import org.joml.Vector4f;
+import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -12,21 +15,23 @@
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import com.mojang.blaze3d.vertex.PoseStack;
+import com.google.common.collect.Iterators;
+import com.llamalad7.mixinextras.injector.ModifyExpressionValue;
+import com.mojang.blaze3d.buffers.GpuBufferSlice;
+import com.mojang.blaze3d.resource.GraphicsResourceAllocator;
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
import dev.engine_room.flywheel.impl.FlwImplXplat;
import dev.engine_room.flywheel.impl.event.RenderContextImpl;
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
-import net.minecraft.client.Camera;
import net.minecraft.client.DeltaTracker;
import net.minecraft.client.multiplayer.ClientLevel;
-import net.minecraft.client.renderer.GameRenderer;
import net.minecraft.client.renderer.LevelRenderer;
-import net.minecraft.client.renderer.LightTexture;
-import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderBuffers;
+import net.minecraft.client.renderer.chunk.ChunkSectionsToRender;
+import net.minecraft.client.renderer.state.level.CameraRenderState;
+import net.minecraft.client.renderer.state.level.LevelRenderState;
import net.minecraft.server.level.BlockDestructionProgress;
import net.minecraft.world.entity.Entity;
@@ -44,14 +49,18 @@ abstract class LevelRendererMixin {
@Final
private Long2ObjectMap> destructionProgress;
+ @Shadow
+ @Final
+ private LevelRenderState levelRenderState;
+
@Unique
@Nullable
private RenderContextImpl flywheel$renderContext;
- // @Inject(method = "renderLevel", at = @At("HEAD"))
- @Inject(method = "renderLevel", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"))
- private void flywheel$beginRender(DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f modelMatrix, Matrix4f projectionMatrix, CallbackInfo ci) {
- flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, modelMatrix, projectionMatrix, camera, deltaTracker.getGameTimeDeltaPartialTick(false));
+ @Inject(method = "renderLevel", at = @At("HEAD"))
+ private void flywheel$beginRender(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, ChunkSectionsToRender chunkSectionsToRender, CallbackInfo ci) {
+ Matrix4f projectionMatrix = RenderContextImpl.PROJECTION_MATRIX_NO_BOB.get();
+ flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, modelViewMatrix, projectionMatrix, cameraState, levelRenderState, deltaTracker.getGameTimeDeltaPartialTick(false));
VisualizationManager manager = VisualizationManager.get(level);
if (manager != null) {
@@ -71,7 +80,7 @@ abstract class LevelRendererMixin {
}
}
- @Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=blockentities"))
+ @Inject(method = "lambda$addMainPass$0", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;submitBlockEntities(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/state/level/LevelRenderState;Lnet/minecraft/client/renderer/SubmitNodeStorage;)V"))
private void flywheel$beforeBlockEntities(CallbackInfo ci) {
if (flywheel$renderContext != null) {
VisualizationManager manager = VisualizationManager.get(level);
@@ -81,7 +90,7 @@ abstract class LevelRendererMixin {
}
}
- @Inject(method = "renderLevel", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiling/ProfilerFiller;popPush(Ljava/lang/String;)V", args = "ldc=destroyProgress"))
+ @Inject(method = "lambda$addMainPass$0", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/LevelRenderer;submitBlockDestroyAnimation(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/SubmitNodeCollector;Lnet/minecraft/client/renderer/state/level/LevelRenderState;)V"))
private void flywheel$beforeRenderCrumbling(CallbackInfo ci) {
if (flywheel$renderContext != null) {
VisualizationManager manager = VisualizationManager.get(level);
@@ -91,10 +100,9 @@ abstract class LevelRendererMixin {
}
}
- @Inject(method = "renderEntity", at = @At("HEAD"), cancellable = true)
- private void flywheel$decideNotToRenderEntity(Entity entity, double camX, double camY, double camZ, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, CallbackInfo ci) {
- if (VisualizationManager.supportsVisualization(entity.level()) && VisualizationHelper.skipVanillaRender(entity)) {
- ci.cancel();
- }
+ @ModifyExpressionValue(method = "extractVisibleEntities", at = @At(value = "INVOKE", target = "Ljava/lang/Iterable;iterator()Ljava/util/Iterator;"))
+ private Iterator flywheel$decideNotToRenderEntity(Iterator original) {
+ return Iterators.filter(original, entity -> !(VisualizationManager.supportsVisualization(entity.level()) &&
+ VisualizationHelper.skipVanillaRender(entity)));
}
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/PoseStackAccessor.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/PoseStackAccessor.java
deleted file mode 100644
index 22478d2a3..000000000
--- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/PoseStackAccessor.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package dev.engine_room.flywheel.impl.mixin;
-
-import java.util.Deque;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.gen.Accessor;
-
-import com.mojang.blaze3d.vertex.PoseStack;
-
-@Mixin(PoseStack.class)
-public interface PoseStackAccessor {
- @Accessor("poseStack")
- Deque flywheel$getPoseStack();
-}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/fix/FixFabulousDepthMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/fix/FixFabulousDepthMixin.java
index e8c79651d..69cc330de 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/fix/FixFabulousDepthMixin.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/fix/FixFabulousDepthMixin.java
@@ -1,18 +1,14 @@
package dev.engine_room.flywheel.impl.mixin.fix;
import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-import com.mojang.blaze3d.platform.GlStateManager;
import net.minecraft.client.renderer.LevelRenderer;
@Mixin(LevelRenderer.class)
abstract class FixFabulousDepthMixin {
- @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/PostChain;process(F)V", ordinal = 1))
- private void flywheel$disableTransparencyShaderDepth(CallbackInfo ci) {
- GlStateManager._depthMask(false);
- }
+ // TODO 1.21.11: Is this still needed?
+// @Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/PostChain;process(F)V", ordinal = 1))
+// private void flywheel$disableTransparencyShaderDepth(CallbackInfo ci) {
+// GlStateManager._depthMask(false);
+// }
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/visualmanage/BlockEntityMixin.java b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/visualmanage/BlockEntityMixin.java
index 5d6ae99ef..86cb2104a 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/mixin/visualmanage/BlockEntityMixin.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/mixin/visualmanage/BlockEntityMixin.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl.mixin.visualmanage;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/registry/IdRegistryImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/registry/IdRegistryImpl.java
index 3ea57ea30..b2df5eeeb 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/registry/IdRegistryImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/registry/IdRegistryImpl.java
@@ -4,7 +4,7 @@
import java.util.Iterator;
import java.util.Set;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import org.jetbrains.annotations.UnmodifiableView;
import dev.engine_room.flywheel.api.registry.IdRegistry;
@@ -20,14 +20,14 @@
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.ReferenceCollection;
import it.unimi.dsi.fastutil.objects.ReferenceCollections;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.resources.Identifier;
public class IdRegistryImpl implements IdRegistry {
private static final ObjectList> ALL = new ObjectArrayList<>();
- private final Object2ReferenceMap map = Object2ReferenceMaps.synchronize(new Object2ReferenceOpenHashMap<>());
- private final Reference2ObjectMap reverseMap = Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>());
- private final ObjectSet keysView = ObjectSets.unmodifiable(map.keySet());
+ private final Object2ReferenceMap map = Object2ReferenceMaps.synchronize(new Object2ReferenceOpenHashMap<>());
+ private final Reference2ObjectMap reverseMap = Reference2ObjectMaps.synchronize(new Reference2ObjectOpenHashMap<>());
+ private final ObjectSet keysView = ObjectSets.unmodifiable(map.keySet());
private final ReferenceCollection valuesView = ReferenceCollections.unmodifiable(map.values());
private boolean frozen;
@@ -36,7 +36,7 @@ public IdRegistryImpl() {
}
@Override
- public void register(ResourceLocation id, T object) {
+ public void register(Identifier id, T object) {
if (frozen) {
throw new IllegalStateException("Cannot register to frozen registry!");
}
@@ -44,32 +44,32 @@ public void register(ResourceLocation id, T object) {
if (oldValue != null) {
throw new IllegalArgumentException("Cannot override registration for ID '" + id + "'!");
}
- ResourceLocation oldId = reverseMap.put(object, id);
+ Identifier oldId = reverseMap.put(object, id);
if (oldId != null) {
throw new IllegalArgumentException("Cannot override ID '" + id + "' with registration for ID '" + oldId + "'!");
}
}
@Override
- public S registerAndGet(ResourceLocation id, S object) {
+ public S registerAndGet(Identifier id, S object) {
register(id, object);
return object;
}
@Override
@Nullable
- public T get(ResourceLocation id) {
+ public T get(Identifier id) {
return map.get(id);
}
@Override
@Nullable
- public ResourceLocation getId(T object) {
+ public Identifier getId(T object) {
return reverseMap.get(object);
}
@Override
- public T getOrThrow(ResourceLocation id) {
+ public T getOrThrow(Identifier id) {
T object = get(id);
if (object == null) {
throw new IllegalArgumentException("Could not find object for ID '" + id + "'!");
@@ -78,8 +78,8 @@ public T getOrThrow(ResourceLocation id) {
}
@Override
- public ResourceLocation getIdOrThrow(T object) {
- ResourceLocation id = getId(object);
+ public Identifier getIdOrThrow(T object) {
+ Identifier id = getId(object);
if (id == null) {
throw new IllegalArgumentException("Could not find ID for object!");
}
@@ -88,7 +88,7 @@ public ResourceLocation getIdOrThrow(T object) {
@Override
@UnmodifiableView
- public Set getAllIds() {
+ public Set getAllIds() {
return keysView;
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/task/Flag.java b/common/src/main/java/dev/engine_room/flywheel/impl/task/Flag.java
index e726f84c9..4807e2455 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/task/Flag.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/task/Flag.java
@@ -2,7 +2,7 @@
import java.util.concurrent.atomic.AtomicBoolean;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A flag that can be raised and lowered in a thread-safe fashion.
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/task/ParallelTaskExecutor.java b/common/src/main/java/dev/engine_room/flywheel/impl/task/ParallelTaskExecutor.java
index 066d2ba82..e52b710b1 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/task/ParallelTaskExecutor.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/task/ParallelTaskExecutor.java
@@ -84,8 +84,7 @@ public void stopWorkers() {
for (Thread thread : threads) {
try {
thread.join();
- } catch (InterruptedException e) {
- //
+ } catch (InterruptedException _) {
}
}
@@ -188,6 +187,11 @@ private void processTask(Runnable task) {
}
}
+ @Override
+ public void shutdown() {
+ stopWorkers();
+ }
+
private class WorkerThread extends Thread {
private int errorLogLatch = MAX_ERRORS_LOGGED_PER_THREAD;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/task/SerialTaskExecutor.java b/common/src/main/java/dev/engine_room/flywheel/impl/task/SerialTaskExecutor.java
index 1eaffdff3..6470ba985 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/task/SerialTaskExecutor.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/task/SerialTaskExecutor.java
@@ -31,4 +31,8 @@ public boolean syncWhile(BooleanSupplier cond) {
@Override
public void syncPoint() {
}
+
+ @Override
+ public void shutdown() {
+ }
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/task/TaskExecutorImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/task/TaskExecutorImpl.java
index 99eda8aa4..fcf07ec42 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/task/TaskExecutorImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/task/TaskExecutorImpl.java
@@ -38,4 +38,12 @@ public interface TaskExecutorImpl extends TaskExecutor {
* try to use {@link #syncUntil(BooleanSupplier) syncUntil}.
*/
void syncPoint();
+
+ /**
+ * Start shutting down this task executor.
+ *
+ * Any attempts to use the current executor after calling this will result in
+ * an exception being thrown unless the executor has been started again.
+ */
+ void shutdown();
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visual/DynamicVisualContextImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visual/DynamicVisualContextImpl.java
index 09803bdae..fe9f13162 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visual/DynamicVisualContextImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visual/DynamicVisualContextImpl.java
@@ -4,8 +4,8 @@
import dev.engine_room.flywheel.api.visual.DistanceUpdateLimiter;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
-import net.minecraft.client.Camera;
+import net.minecraft.client.renderer.state.level.CameraRenderState;
-public record DynamicVisualContextImpl(Camera camera, FrustumIntersection frustum, float partialTick,
- DistanceUpdateLimiter limiter) implements DynamicVisual.Context {
+public record DynamicVisualContextImpl(CameraRenderState cameraRenderState, FrustumIntersection frustum, float partialTick,
+ DistanceUpdateLimiter limiter) implements DynamicVisual.Context {
}
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 9ad215370..f89230fd5 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
@@ -5,9 +5,9 @@
import java.util.SortedSet;
import org.jetbrains.annotations.Contract;
-import org.jetbrains.annotations.Nullable;
import org.joml.FrustumIntersection;
import org.joml.Matrix4f;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.backend.BackendManager;
import dev.engine_room.flywheel.api.backend.Engine;
@@ -112,7 +112,7 @@ private LateInit(LevelAccessor level) {
var update = MapContextPlan.map(this::createVisualFrameContext)
.to(NestedPlan.of(blockEntities.framePlan(visualizationContext), entities.framePlan(visualizationContext), effects.framePlan(visualizationContext)));
- framePlan = IfElsePlan.on((RenderContext ctx) -> engine.updateRenderOrigin(ctx.camera()))
+ framePlan = IfElsePlan.on((RenderContext ctx) -> engine.updateRenderOrigin(ctx.cameraRenderState()))
.ifTrue(recreate)
.ifFalse(update)
.plan()
@@ -134,14 +134,13 @@ private LateInit(LevelAccessor level) {
private DynamicVisual.Context createVisualFrameContext(RenderContext ctx) {
Vec3i renderOrigin = engine.renderOrigin();
- var cameraPos = ctx.camera()
- .getPosition();
+ var cameraPos = ctx.cameraRenderState().pos;
Matrix4f viewProjection = new Matrix4f(ctx.viewProjection());
viewProjection.translate((float) (renderOrigin.getX() - cameraPos.x), (float) (renderOrigin.getY() - cameraPos.y), (float) (renderOrigin.getZ() - cameraPos.z));
FrustumIntersection frustum = new FrustumIntersection(viewProjection);
- return new DynamicVisualContextImpl(ctx.camera(), frustum, ctx.partialTick(), frameLimiter);
+ return new DynamicVisualContextImpl(ctx.cameraRenderState(), frustum, ctx.partialTick(), frameLimiter);
}
}
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java
index 43d605ed0..30fc255c6 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/VisualizerRegistryImpl.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl.visualization;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
diff --git a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/BlockEntityStorage.java b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/BlockEntityStorage.java
index 86af9070b..b56518480 100644
--- a/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/BlockEntityStorage.java
+++ b/common/src/main/java/dev/engine_room/flywheel/impl/visualization/storage/BlockEntityStorage.java
@@ -1,6 +1,6 @@
package dev.engine_room.flywheel.impl.visualization.storage;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visual.BlockEntityVisual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
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 8bc84204b..05190c541 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
@@ -5,7 +5,7 @@
import java.util.List;
import java.util.Map;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.task.Plan;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
diff --git a/common/src/main/resources/assets/flywheel/lang/en_us.json b/common/src/main/resources/assets/flywheel/lang/en_us.json
index a8d0d041c..7f780b3f7 100644
--- a/common/src/main/resources/assets/flywheel/lang/en_us.json
+++ b/common/src/main/resources/assets/flywheel/lang/en_us.json
@@ -6,9 +6,9 @@
"command.flywheel.limit_updates.get.off": "Update limiting is currently disabled",
"command.flywheel.limit_updates.get.on": "Update limiting is currently enabled",
"command.flywheel.limit_updates.set.off": "Update limiting is now disabled",
- "command.flywheel.limit_updates.set.on" : "Update limiting is now enabled",
- "command.flywheel.use_light_directions.get.off" : "Not using light directions",
- "command.flywheel.use_light_directions.get.on" : "Using light directions",
- "command.flywheel.use_light_directions.set.off" : "Set light directions to off",
- "command.flywheel.use_light_directions.set.on" : "Set light directions to on"
+ "command.flywheel.limit_updates.set.on": "Update limiting is now enabled",
+ "command.flywheel.use_light_directions.get.off": "Not using light directions",
+ "command.flywheel.use_light_directions.get.on": "Using light directions",
+ "command.flywheel.use_light_directions.set.off": "Set light directions to off",
+ "command.flywheel.use_light_directions.set.on": "Set light directions to on"
}
diff --git a/common/src/main/resources/flywheel.impl.mixins.json b/common/src/main/resources/flywheel.impl.mixins.json
index 9b576d52d..ed625203b 100644
--- a/common/src/main/resources/flywheel.impl.mixins.json
+++ b/common/src/main/resources/flywheel.impl.mixins.json
@@ -2,17 +2,17 @@
"required": true,
"minVersion": "0.8",
"package": "dev.engine_room.flywheel.impl.mixin",
- "compatibilityLevel": "JAVA_21",
- "refmap": "flywheel.refmap.json",
+ "compatibilityLevel": "JAVA_25",
"client": [
"BlockEntityTypeMixin",
"ClientChunkCacheMixin",
+ "EntityRendererAccessor",
"EntityTypeMixin",
+ "GameRendererMixin",
"LevelMixin",
"LevelRendererMixin",
"MinecraftMixin",
"ModelPartAccessor",
- "PoseStackAccessor",
"PoseStackMixin",
"fix.FixFabulousDepthMixin",
"visualmanage.BlockEntityMixin",
diff --git a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/MockShaderSources.java b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/MockShaderSources.java
index 4403088a5..d2a4d4bd6 100644
--- a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/MockShaderSources.java
+++ b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/MockShaderSources.java
@@ -7,56 +7,56 @@
import java.util.List;
import java.util.Map;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.resources.Identifier;
public class MockShaderSources {
- private final Map sources = new HashMap<>();
- private final Map cache = new HashMap<>();
- private final Deque findStack = new ArrayDeque<>();
+ private final Map sources = new HashMap<>();
+ private final Map cache = new HashMap<>();
+ private final Deque findStack = new ArrayDeque<>();
public MockShaderSources() {
}
- public void add(ResourceLocation loc, String source) {
+ public void add(Identifier loc, String source) {
sources.put(loc, source);
}
- public LoadResult find(ResourceLocation location) {
- if (findStack.contains(location)) {
- // Make a copy of the find stack with the offending location added on top to show the full path.
- findStack.addLast(location);
+ public LoadResult find(Identifier id) {
+ if (findStack.contains(id)) {
+ // Make a copy of the find stack with the offending id added on top to show the full path.
+ findStack.addLast(id);
var copy = List.copyOf(findStack);
findStack.removeLast();
- return new LoadResult.Failure(new LoadError.CircularDependency(location, copy));
+ return new LoadResult.Failure(new LoadError.CircularDependency(id, copy));
}
- findStack.addLast(location);
+ findStack.addLast(id);
- LoadResult out = load(location);
+ LoadResult out = load(id);
findStack.removeLast();
return out;
}
- private LoadResult load(ResourceLocation loc) {
- var out = cache.get(loc);
+ private LoadResult load(Identifier id) {
+ var out = cache.get(id);
if (out != null) {
return out;
}
- var loadResult = _load(loc);
+ var loadResult = _load(id);
- cache.put(loc, loadResult);
+ cache.put(id, loadResult);
return loadResult;
}
- private LoadResult _load(ResourceLocation loc) {
- var maybeFound = sources.get(loc);
+ private LoadResult _load(Identifier id) {
+ var maybeFound = sources.get(id);
if (maybeFound == null) {
- return new LoadResult.Failure(new LoadError.IOError(loc, new FileNotFoundException(loc.toString())));
+ return new LoadResult.Failure(new LoadError.IOError(id, new FileNotFoundException(id.toString())));
}
- return SourceFile.parse(this::find, loc, maybeFound);
+ return SourceFile.parse(this::find, id, maybeFound);
}
}
diff --git a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestBase.java b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestBase.java
index 1e2860eb1..33dc85c7b 100644
--- a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestBase.java
+++ b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestBase.java
@@ -6,20 +6,20 @@
import java.util.List;
-import dev.engine_room.flywheel.lib.util.ResourceUtil;
-import net.minecraft.resources.ResourceLocation;
+import dev.engine_room.flywheel.lib.util.IdentifierUtil;
+import net.minecraft.resources.Identifier;
public class TestBase {
- public static final ResourceLocation FLW_A = ResourceUtil.rl("a.glsl");
- public static final ResourceLocation FLW_B = ResourceUtil.rl("b.glsl");
- public static final ResourceLocation FLW_C = ResourceUtil.rl("c.glsl");
+ public static final Identifier FLW_A = IdentifierUtil.id("a.glsl");
+ public static final Identifier FLW_B = IdentifierUtil.id("b.glsl");
+ public static final Identifier FLW_C = IdentifierUtil.id("c.glsl");
public static T assertSingletonList(List list) {
assertEquals(1, list.size());
return list.get(0);
}
- public static E findAndAssertError(Class clazz, MockShaderSources sources, ResourceLocation loc) {
+ public static E findAndAssertError(Class clazz, MockShaderSources sources, Identifier loc) {
var result = sources.find(loc);
var failure = assertInstanceOf(LoadResult.Failure.class, result);
return assertInstanceOf(clazz, failure.error());
@@ -36,12 +36,12 @@ static E assertSimpleNestedErrorsToDepth(Class finalErr
return assertInstanceOf(finalErrType, pair.getSecond());
}
- public static SourceFile findAndAssertSuccess(MockShaderSources sources, ResourceLocation loc) {
- var result = sources.find(loc);
- return assertSuccessAndUnwrap(loc, result);
+ public static SourceFile findAndAssertSuccess(MockShaderSources sources, Identifier id) {
+ var result = sources.find(id);
+ return assertSuccessAndUnwrap(id, result);
}
- public static SourceFile assertSuccessAndUnwrap(ResourceLocation expectedName, LoadResult result) {
+ public static SourceFile assertSuccessAndUnwrap(Identifier expectedName, LoadResult result) {
assertInstanceOf(LoadResult.Success.class, result);
var file = result.unwrap();
diff --git a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestErrorMessages.java b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestErrorMessages.java
index f1eff161d..26c06f476 100644
--- a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestErrorMessages.java
+++ b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestErrorMessages.java
@@ -7,7 +7,7 @@
import org.junit.jupiter.api.Test;
import dev.engine_room.flywheel.backend.glsl.error.ErrorBuilder;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.resources.Identifier;
public class TestErrorMessages extends TestBase {
@BeforeAll
@@ -54,14 +54,14 @@ void testNestedIncludeMsg() {
""", sources, FLW_A);
}
- public static void assertErrorMatches(String expected, MockShaderSources sources, ResourceLocation loc) {
- var message = assertErrorAndGetMessage(sources, loc).build();
+ public static void assertErrorMatches(String expected, MockShaderSources sources, Identifier id) {
+ var message = assertErrorAndGetMessage(sources, id).build();
assertEquals(expected.trim(), message.trim());
}
- public static ErrorBuilder assertErrorAndGetMessage(MockShaderSources sources, ResourceLocation loc) {
- var result = sources.find(loc);
+ public static ErrorBuilder assertErrorAndGetMessage(MockShaderSources sources, Identifier id) {
+ var result = sources.find(id);
var failure = assertInstanceOf(LoadResult.Failure.class, result);
return failure.error()
.generateMessage();
diff --git a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestShaderSourceLoading.java b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestShaderSourceLoading.java
index 57c635756..afbcb842a 100644
--- a/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestShaderSourceLoading.java
+++ b/common/src/test/java/dev/engine_room/flywheel/backend/glsl/TestShaderSourceLoading.java
@@ -48,7 +48,7 @@ void testMissingInclude() {
var aErr = findAndAssertError(LoadError.IncludeError.class, sources, FLW_A);
var ioErr = assertSimpleNestedErrorsToDepth(LoadError.IOError.class, aErr, 1);
- assertEquals(FLW_B, ioErr.location());
+ assertEquals(FLW_B, ioErr.id());
}
@Test
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/item/ItemModels.java b/common/src/vanillin/java/dev/engine_room/vanillin/item/ItemModels.java
deleted file mode 100644
index 4b9119e77..000000000
--- a/common/src/vanillin/java/dev/engine_room/vanillin/item/ItemModels.java
+++ /dev/null
@@ -1,299 +0,0 @@
-package dev.engine_room.vanillin.item;
-
-import java.nio.ByteBuffer;
-import java.nio.IntBuffer;
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.jetbrains.annotations.Nullable;
-import org.joml.Matrix3f;
-import org.joml.Matrix4f;
-import org.joml.Vector3f;
-import org.joml.Vector4f;
-import org.lwjgl.system.MemoryStack;
-
-import com.mojang.blaze3d.vertex.DefaultVertexFormat;
-import com.mojang.blaze3d.vertex.PoseStack;
-
-import dev.engine_room.flywheel.api.material.Material;
-import dev.engine_room.flywheel.api.material.Transparency;
-import dev.engine_room.flywheel.api.model.Mesh;
-import dev.engine_room.flywheel.api.model.Model;
-import dev.engine_room.flywheel.lib.material.Materials;
-import dev.engine_room.flywheel.lib.material.SimpleMaterial;
-import dev.engine_room.flywheel.lib.memory.MemoryBlock;
-import dev.engine_room.flywheel.lib.model.ModelUtil;
-import dev.engine_room.flywheel.lib.model.SimpleModel;
-import dev.engine_room.flywheel.lib.model.SimpleQuadMesh;
-import dev.engine_room.flywheel.lib.model.SingleMeshModel;
-import dev.engine_room.flywheel.lib.util.RendererReloadCache;
-import dev.engine_room.flywheel.lib.vertex.FullVertexView;
-import dev.engine_room.vanillin.Vanillin;
-import dev.engine_room.vanillin.VanillinXplat;
-import dev.engine_room.vanillin.mixin.item.ItemOverridesAccessor;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.multiplayer.ClientLevel;
-import net.minecraft.client.renderer.ItemBlockRenderTypes;
-import net.minecraft.client.renderer.block.model.BakedQuad;
-import net.minecraft.client.renderer.block.model.ItemOverrides;
-import net.minecraft.client.renderer.texture.OverlayTexture;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.client.resources.model.ModelResourceLocation;
-import net.minecraft.client.resources.model.MultiPartBakedModel;
-import net.minecraft.client.resources.model.SimpleBakedModel;
-import net.minecraft.client.resources.model.WeightedBakedModel;
-import net.minecraft.core.Direction;
-import net.minecraft.core.registries.Registries;
-import net.minecraft.data.models.ItemModelGenerators;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.tags.TagKey;
-import net.minecraft.util.RandomSource;
-import net.minecraft.world.item.BlockItem;
-import net.minecraft.world.item.Item;
-import net.minecraft.world.item.ItemDisplayContext;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.Items;
-import net.minecraft.world.level.Level;
-import net.minecraft.world.level.block.HalfTransparentBlock;
-import net.minecraft.world.level.block.StainedGlassPaneBlock;
-
-public class ItemModels {
- public static final TagKey- NO_INSTANCING = TagKey.create(Registries.ITEM, Vanillin.rl("no_instancing"));
-
- private static final Model EMPTY_MODEL = new SimpleModel(List.of());
- private static final RendererReloadCache MESH_CACHE = new RendererReloadCache<>(key -> bakeMesh(key.model(), key.displayContext()));
- private static final RendererReloadCache MODEL_CACHE = new RendererReloadCache<>(key -> bakeModel(key.model(), key.displayContext(), key.material(), key.foil()));
-
- private static final ModelResourceLocation TRIDENT_MODEL = ModelResourceLocation.vanilla("trident", "inventory");
- private static final ModelResourceLocation SPYGLASS_MODEL = ModelResourceLocation.vanilla("spyglass", "inventory");
-
- private static final @Nullable Direction[] DIRECTIONS = new Direction[]{Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, null};
-
- private static final Set ALLOWED_OVERRIDES = new HashSet<>();
-
- static {
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("lefthanded"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("cooldown"));
- ALLOWED_OVERRIDES.add(ItemModelGenerators.TRIM_TYPE_PREDICATE_ID);
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("custom_model_data"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("pull"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("brushing"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("pulling"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("filled"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("charged"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("firework"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("broken"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("cast"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("blocking"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("throwing"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("level"));
- ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("tooting"));
- }
-
- public static boolean isSupported(ItemStack stack) {
- return !stack.is(NO_INSTANCING) && doesNotHaveItemColors(stack.getItem()) && isSupported(getModel(stack));
- }
-
- private static boolean doesNotHaveItemColors(Item item) {
- return VanillinXplat.INSTANCE.itemColors(item) == null;
- }
-
- public static BakedModel getModel(ItemStack stack) {
- return Minecraft.getInstance()
- .getItemRenderer()
- .getItemModelShaper()
- .getItemModel(stack);
- }
-
- @Nullable
- public static BakedModel getActualBakedModel(@Nullable ClientLevel clientLevel, ItemStack itemStack, ItemDisplayContext displayContext) {
- if (itemStack.isEmpty()) {
- return null;
- }
-
- var baseModel = getModel(itemStack);
- var overrides = baseModel.getOverrides();
- var model = overrides.resolve(baseModel, itemStack, clientLevel, null, 0);
-
- if (model == null) {
- model = baseModel;
- }
-
- boolean notEquipped = displayContext == ItemDisplayContext.GUI || displayContext == ItemDisplayContext.GROUND || displayContext == ItemDisplayContext.FIXED;
- if (model.isCustomRenderer() || itemStack.is(Items.TRIDENT) && !notEquipped) {
- return null;
- }
-
- if (notEquipped) {
- if (itemStack.is(Items.TRIDENT)) {
- model = Minecraft.getInstance()
- .getItemRenderer()
- .getItemModelShaper()
- .getModelManager()
- .getModel(TRIDENT_MODEL);
- } else if (itemStack.is(Items.SPYGLASS)) {
- model = Minecraft.getInstance()
- .getItemRenderer()
- .getItemModelShaper()
- .getModelManager()
- .getModel(SPYGLASS_MODEL);
- }
- }
-
- return model;
- }
-
- public static boolean isSupported(BakedModel model) {
- if (model.isCustomRenderer()) {
- return false;
- }
-
- var overrides = model.getOverrides();
- if (overrides != ItemOverrides.EMPTY) {
- var properties = ((ItemOverridesAccessor) overrides).vanillin$properties();
-
- for (var property : properties) {
- if (!ALLOWED_OVERRIDES.contains(property)) {
- return false;
- }
- }
- }
-
- // Check for class equality rather than instanceof to ensure subclasses are *not* handled by vanillin.
- Class extends BakedModel> c = model.getClass();
- if (!(c == SimpleBakedModel.class || c == MultiPartBakedModel.class || c == WeightedBakedModel.class)) {
- return false;
- }
-
- return true;
- }
-
- public static Model get(Level level, ItemStack itemStack, ItemDisplayContext displayContext) {
- boolean cull = displayContext == ItemDisplayContext.GUI || displayContext.firstPerson() || !(itemStack.getItem() instanceof BlockItem block) || !(block.getBlock() instanceof HalfTransparentBlock) && !(block.getBlock() instanceof StainedGlassPaneBlock);
- var material = ModelUtil.getItemMaterial(ItemBlockRenderTypes.getRenderType(itemStack, cull));
-
- if (material == null) {
- material = Materials.TRANSLUCENT_ENTITY;
- }
-
- if (itemStack.getItem() instanceof BlockItem && material.transparency() == Transparency.TRANSLUCENT) {
- material = SimpleMaterial.builderOf(material)
- .transparency(Transparency.ORDER_INDEPENDENT)
- .build();
- }
-
- // Visuals all hold references to Level so use that as the parameter type for convenience and cast here.
- ClientLevel clientLevel = (level instanceof ClientLevel) ? (ClientLevel) level : null;
-
- BakedModel model = getActualBakedModel(clientLevel, itemStack, displayContext);
-
- if (model == null) {
- return EMPTY_MODEL;
- }
-
- return MODEL_CACHE.get(new BakedModelKey(model, displayContext, material, itemStack.hasFoil()));
- }
-
- public static Model bakeModel(BakedModel model, ItemDisplayContext displayContext, Material material, boolean foil) {
- var mesh = MESH_CACHE.get(new BakedMeshKey(model, displayContext));
-
- if (foil) {
- return new SimpleModel(List.of(new Model.ConfiguredMesh(material, mesh), new Model.ConfiguredMesh(Materials.GLINT, mesh)));
- } else {
- return new SingleMeshModel(mesh, material);
- }
- }
-
- public static Mesh bakeMesh(BakedModel model, ItemDisplayContext displayContext) {
- boolean leftHand = displayContext == ItemDisplayContext.FIRST_PERSON_LEFT_HAND || displayContext == ItemDisplayContext.THIRD_PERSON_LEFT_HAND;
-
- var poseStack = new PoseStack();
-
- model.getTransforms()
- .getTransform(displayContext)
- .apply(leftHand, poseStack);
- poseStack.translate(-0.5f, -0.5f, -0.5f);
-
- RandomSource randomSource = RandomSource.create();
-
- // Write all BakedQuads into a list first to get a count so we can allocate memory ahead of time.
- List allQuads = new ArrayList<>();
- for (Direction value : DIRECTIONS) {
- randomSource.setSeed(42L);
- allQuads.addAll(model.getQuads(null, value, randomSource));
- }
-
- int vertexCount = allQuads.size() * 4;
- var memoryBlock = MemoryBlock.mallocTracked(vertexCount * FullVertexView.STRIDE);
- var meshVertices = new FullVertexView();
-
- meshVertices.nativeMemoryOwner(memoryBlock);
- meshVertices.ptr(memoryBlock.ptr());
- meshVertices.vertexCount(vertexCount);
-
- Vector4f position = new Vector4f();
- Vector3f normal = new Vector3f();
-
- Matrix4f poseMatrix = poseStack.last()
- .pose();
- Matrix3f normalMatrix = poseStack.last()
- .normal();
-
- try (MemoryStack memoryStack = MemoryStack.stackPush();) {
- ByteBuffer byteBuffer = memoryStack.malloc(DefaultVertexFormat.BLOCK.getVertexSize());
- IntBuffer intBuffer = byteBuffer.asIntBuffer();
-
- int vertex = 0;
-
- for (BakedQuad quad : allQuads) {
- SodiumAnimatedTextureCompat.add(quad.getSprite());
-
- int[] js = quad.getVertices();
- var direction = quad.getDirection();
-
- normal.set(direction.getStepX(), direction.getStepY(), direction.getStepZ());
- normal.mul(normalMatrix);
-
- int j = js.length / 8;
-
- for (int k = 0; k < j; ++k) {
- intBuffer.clear();
- intBuffer.put(js, k * 8, 8);
-
- position.set(byteBuffer.getFloat(0), byteBuffer.getFloat(4), byteBuffer.getFloat(8), 1.0f);
- position.mul(poseMatrix);
-
- // We could probably handle item colors here.
- meshVertices.x(vertex, position.x());
- meshVertices.y(vertex, position.y());
- meshVertices.z(vertex, position.z());
- meshVertices.r(vertex, 1.0f);
- meshVertices.g(vertex, 1.0f);
- meshVertices.b(vertex, 1.0f);
- meshVertices.a(vertex, 1.0f);
- meshVertices.u(vertex, byteBuffer.getFloat(16));
- meshVertices.v(vertex, byteBuffer.getFloat(20));
- meshVertices.overlay(vertex, OverlayTexture.NO_OVERLAY);
- meshVertices.light(vertex, 0);
- meshVertices.normalX(vertex, normal.x());
- meshVertices.normalY(vertex, normal.y());
- meshVertices.normalZ(vertex, normal.z());
-
- vertex++;
- }
- }
- }
-
- return new SimpleQuadMesh(meshVertices);
- }
-
- public record BakedModelKey(BakedModel model, ItemDisplayContext displayContext, Material material, boolean foil) {
-
- }
-
- public record BakedMeshKey(BakedModel model, ItemDisplayContext displayContext) {
-
- }
-}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/mixin/item/ItemOverridesAccessor.java b/common/src/vanillin/java/dev/engine_room/vanillin/mixin/item/ItemOverridesAccessor.java
deleted file mode 100644
index e0b1fc167..000000000
--- a/common/src/vanillin/java/dev/engine_room/vanillin/mixin/item/ItemOverridesAccessor.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package dev.engine_room.vanillin.mixin.item;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.gen.Accessor;
-
-import net.minecraft.client.renderer.block.model.ItemOverrides;
-import net.minecraft.resources.ResourceLocation;
-
-@Mixin(ItemOverrides.class)
-public interface ItemOverridesAccessor {
- @Accessor("properties")
- ResourceLocation[] vanillin$properties();
-}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java
deleted file mode 100644
index ce118e09f..000000000
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java
+++ /dev/null
@@ -1,144 +0,0 @@
-package dev.engine_room.vanillin.visuals;
-
-import com.mojang.math.Transformation;
-
-import dev.engine_room.flywheel.api.visualization.VisualizationContext;
-import dev.engine_room.flywheel.lib.instance.InstanceTypes;
-import dev.engine_room.flywheel.lib.instance.TransformedInstance;
-import dev.engine_room.flywheel.lib.model.Models;
-import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual;
-import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
-import dev.engine_room.flywheel.lib.visual.component.ShadowComponent;
-import dev.engine_room.vanillin.item.ItemModels;
-import net.minecraft.client.Camera;
-import net.minecraft.util.Mth;
-import net.minecraft.world.entity.Display;
-import net.minecraft.world.entity.Entity;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.level.block.Blocks;
-import net.minecraft.world.phys.Vec3;
-
-public class ItemDisplayVisual extends AbstractEntityVisual implements SimpleDynamicVisual {
- private final TransformedInstance instance;
-
- private ItemStack currentStack;
-
- private final ShadowComponent shadowComponent;
-
- public ItemDisplayVisual(VisualizationContext ctx, Display.ItemDisplay entity, float partialTick) {
- super(ctx, entity, partialTick);
-
- var itemRenderState = entity.itemRenderState();
-
- if (itemRenderState == null) {
- currentStack = ItemStack.EMPTY;
- instance = ctx.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, Models.block(Blocks.AIR.defaultBlockState()))
- .createInstance();
- } else {
- currentStack = itemRenderState.itemStack()
- .copy();
- instance = ctx.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, currentStack, itemRenderState.itemTransform()))
- .createInstance();
- }
-
- shadowComponent = new ShadowComponent(ctx, entity);
- }
-
- @Override
- public void beginFrame(Context ctx) {
- Display.RenderState renderState = entity.renderState();
- if (renderState == null) {
- instance.handle()
- .setVisible(false);
- return;
- }
- var object = entity.itemRenderState();
- if (object == null) {
- instance.handle()
- .setVisible(false);
- return;
- }
-
- instance.handle()
- .setVisible(true);
-
- var itemStack = object.itemStack();
-
- if (!ItemStack.matches(itemStack, currentStack)) {
- currentStack = itemStack.copy();
- visualizationContext.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, currentStack, object.itemTransform()))
- .stealInstance(instance);
- }
-
- float f = entity.calculateInterpolationProgress(ctx.partialTick());
-
- shadowComponent.radius(renderState.shadowRadius()
- .get(f));
- shadowComponent.strength(renderState.shadowStrength()
- .get(f));
- shadowComponent.beginFrame(ctx);
-
- int i = renderState.brightnessOverride();
- int j = i != -1 ? i : computePackedLight(ctx.partialTick());
- Transformation transformation = renderState.transformation()
- .get(f);
-
- Vec3 pos = entity.position();
- var renderOrigin = renderOrigin();
-
- instance.setIdentityTransform()
- .translate((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ()));
-
- float partialTick = ctx.partialTick();
- Camera camera = ctx.camera();
- switch (renderState.billboardConstraints()) {
- case FIXED:
- instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F);
- break;
- case HORIZONTAL:
- instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * cameraXRot(camera), 0.0F);
- break;
- case VERTICAL:
- instance.pose.rotateYXZ(-0.017453292F * cameraYrot(camera), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F);
- break;
- case CENTER:
- instance.pose.rotateYXZ(-0.017453292F * cameraYrot(camera), ((float) Math.PI / 180F) * cameraXRot(camera), 0.0F);
- break;
- }
-
- // getMatrix does a copy which is not strictly necessary here but oh well.
- instance.mul(transformation.getMatrix())
- .rotateY(Mth.PI)
- .light(j)
- .setChanged();
- }
-
- private static float cameraYrot(Camera camera) {
- return camera.getYRot() - 180.0F;
- }
-
- private static float cameraXRot(Camera camera) {
- return -camera.getXRot();
- }
-
- private static float entityYRot(Entity entity, float partialTick) {
- return Mth.rotLerp(partialTick, entity.yRotO, entity.getYRot());
- }
-
- private static float entityXRot(Entity entity, float partialTick) {
- return Mth.lerp(partialTick, entity.xRotO, entity.getXRot());
- }
-
- @Override
- protected void _delete() {
- instance.delete();
- }
-
- public static boolean shouldVisualize(Display.ItemDisplay itemDisplay) {
- var state = itemDisplay.itemRenderState();
- return state != null && ItemModels.isSupported(state.itemStack());
- }
-}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java
deleted file mode 100644
index 7d6a44ce1..000000000
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java
+++ /dev/null
@@ -1,182 +0,0 @@
-package dev.engine_room.vanillin.visuals;
-
-import org.joml.Matrix4f;
-
-import dev.engine_room.flywheel.api.model.Model;
-import dev.engine_room.flywheel.api.visual.EntityVisual;
-import dev.engine_room.flywheel.api.visualization.VisualizationContext;
-import dev.engine_room.flywheel.lib.instance.InstanceTypes;
-import dev.engine_room.flywheel.lib.instance.TransformedInstance;
-import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
-import dev.engine_room.flywheel.lib.util.RendererReloadCache;
-import dev.engine_room.flywheel.lib.visual.AbstractVisual;
-import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
-import dev.engine_room.vanillin.item.ItemModels;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.LightTexture;
-import net.minecraft.client.resources.model.ModelManager;
-import net.minecraft.client.resources.model.ModelResourceLocation;
-import net.minecraft.core.BlockPos;
-import net.minecraft.core.Direction;
-import net.minecraft.util.Mth;
-import net.minecraft.world.entity.EntityType;
-import net.minecraft.world.entity.decoration.ItemFrame;
-import net.minecraft.world.item.ItemDisplayContext;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.item.Items;
-import net.minecraft.world.level.LightLayer;
-
-public class ItemFrameVisual extends AbstractVisual implements EntityVisual, SimpleDynamicVisual {
- private static final ModelResourceLocation FRAME_LOCATION = ModelResourceLocation.vanilla("item_frame", "map=false");
- private static final ModelResourceLocation MAP_FRAME_LOCATION = ModelResourceLocation.vanilla("item_frame", "map=true");
- private static final ModelResourceLocation GLOW_FRAME_LOCATION = ModelResourceLocation.vanilla("glow_item_frame", "map=false");
- private static final ModelResourceLocation GLOW_MAP_FRAME_LOCATION = ModelResourceLocation.vanilla("glow_item_frame", "map=true");
-
- public static final RendererReloadCache MODEL_RESOURCE_LOCATION = new RendererReloadCache<>(mrl -> {
- ModelManager modelManager = Minecraft.getInstance()
- .getModelManager()
- .getBlockModelShaper()
- .getModelManager();
-
- return new BakedModelBuilder(modelManager.getModel(mrl))
- .build();
- });
-
- private final Matrix4f baseTransform = new Matrix4f();
-
- private final TransformedInstance frame;
- private final TransformedInstance item;
- private final ItemFrame entity;
- private ModelResourceLocation lastFrameLocation;
- private ItemStack lastItemStack;
-
- public ItemFrameVisual(VisualizationContext ctx, ItemFrame entity, float partialTick) {
- super(ctx, entity.level(), partialTick);
-
- this.entity = entity;
-
- lastItemStack = entity.getItem()
- .copy();
-
- lastFrameLocation = getFrameModelResourceLoc(entity, lastItemStack);
- var frameModel = MODEL_RESOURCE_LOCATION.get(lastFrameLocation);
-
- frame = ctx.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, frameModel)
- .createInstance();
-
- frame.setTransform(baseTransform);
-
- item = ctx.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, lastItemStack, ItemDisplayContext.FIXED))
- .createInstance();
-
- animate(partialTick);
- }
-
- public static boolean shouldVisualize(ItemFrame entity) {
- // We don't support map rendering, and we can't support exotic item models.
- return !entity.getItem()
- .is(Items.FILLED_MAP) && ItemModels.isSupported(entity.getItem());
- }
-
- @Override
- public void beginFrame(Context ctx) {
- animate(ctx.partialTick());
- }
-
- public void animate(float partialTick) {
- var light = LightTexture.pack(getBlockLightLevel(entity.getPos()), getSkyLightLevel(entity.getPos()));
-
- boolean invisible = entity.isInvisible();
-
- Direction direction = entity.getDirection();
- var origin = visualizationContext.renderOrigin();
-
- float d = 0.46875f;
-
- float x = (float) (entity.getX() - origin.getX() + direction.getStepX() * d);
- float y = (float) (entity.getY() - origin.getY() + direction.getStepY() * d);
- float z = (float) (entity.getZ() - origin.getZ() + direction.getStepZ() * d);
-
- baseTransform.translation(x, y, z);
- baseTransform.rotateXYZ(Mth.DEG_TO_RAD * entity.getXRot(), Mth.DEG_TO_RAD * (180.0f - entity.getYRot()), 0.0f);
-
- var stack = entity.getItem();
- var frameLocation = getFrameModelResourceLoc(entity, stack);
-
- if (frameLocation != lastFrameLocation) {
- visualizationContext.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, MODEL_RESOURCE_LOCATION.get(frameLocation))
- .stealInstance(frame);
- lastFrameLocation = frameLocation;
- }
-
- frame.setVisible(!invisible);
-
- frame.setTransform(baseTransform)
- .translate(-0.5f, -0.5f, -0.5f)
- .light(light)
- .setChanged();
-
- if (!ItemStack.matches(lastItemStack, stack)) {
- lastItemStack = stack.copy();
- visualizationContext.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, lastItemStack, ItemDisplayContext.FIXED))
- .stealInstance(item);
- }
-
- item.setTransform(baseTransform);
-
- if (invisible) {
- item.translate(0.0F, 0.0F, 0.5F);
- } else {
- item.translate(0.0F, 0.0F, 0.4375F);
- }
-
- int i = entity.hasFramedMap() ? entity.getRotation() % 4 * 2 : entity.getRotation();
-
- item.rotateZDegrees(i * 360.0F / 8.0F);
-
- item.scale(0.5F, 0.5F, 0.5F);
-
- item.light(getLightVal(15728880, light))
- .setChanged();
- }
-
- @Override
- public void update(float partialTick) {
-
- }
-
- @Override
- protected void _delete() {
- frame.delete();
- item.delete();
- }
-
- private int getLightVal(int glowLightVal, int regularLightVal) {
- return entity.getType() == EntityType.GLOW_ITEM_FRAME ? glowLightVal : regularLightVal;
- }
-
- protected int getSkyLightLevel(BlockPos pos) {
- return level.getBrightness(LightLayer.SKY, pos);
- }
-
- protected int getBlockLightLevelBase(BlockPos pos) {
- return entity.isOnFire() ? 15 : level.getBrightness(LightLayer.BLOCK, pos);
- }
-
- protected int getBlockLightLevel(BlockPos pos) {
- return entity.getType() == EntityType.GLOW_ITEM_FRAME ? Math.max(5, getBlockLightLevelBase(pos)) : getBlockLightLevelBase(pos);
- }
-
- public static ModelResourceLocation getFrameModelResourceLoc(ItemFrame entity, ItemStack item) {
- boolean bl = entity.getType() == EntityType.GLOW_ITEM_FRAME;
- if (item.is(Items.FILLED_MAP)) {
- return bl ? GLOW_MAP_FRAME_LOCATION : MAP_FRAME_LOCATION;
- } else {
- return bl ? GLOW_FRAME_LOCATION : FRAME_LOCATION;
- }
- }
-}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemVisual.java b/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemVisual.java
deleted file mode 100644
index 5e3aadc64..000000000
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ItemVisual.java
+++ /dev/null
@@ -1,161 +0,0 @@
-package dev.engine_room.vanillin.visuals;
-
-import com.mojang.blaze3d.vertex.PoseStack;
-import com.mojang.math.Axis;
-
-import dev.engine_room.flywheel.api.visualization.VisualizationContext;
-import dev.engine_room.flywheel.lib.instance.InstanceTypes;
-import dev.engine_room.flywheel.lib.instance.TransformedInstance;
-import dev.engine_room.flywheel.lib.transform.TransformStack;
-import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual;
-import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
-import dev.engine_room.flywheel.lib.visual.util.InstanceRecycler;
-import dev.engine_room.vanillin.item.ItemModels;
-import net.minecraft.client.renderer.LightTexture;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.util.Mth;
-import net.minecraft.util.RandomSource;
-import net.minecraft.world.entity.item.ItemEntity;
-import net.minecraft.world.item.Item;
-import net.minecraft.world.item.ItemDisplayContext;
-import net.minecraft.world.item.ItemStack;
-import net.minecraft.world.level.LightLayer;
-
-public class ItemVisual extends AbstractEntityVisual implements SimpleDynamicVisual {
-
- private static final ThreadLocal RANDOM = ThreadLocal.withInitial(RandomSource::createNewThreadLocalInstance);
-
- private final PoseStack pPoseStack = new PoseStack();
- private BakedModel bakedModel;
- private ItemStack currentStack;
-
- private InstanceRecycler instances;
-
- public ItemVisual(VisualizationContext ctx, ItemEntity entity, float partialTick) {
- super(ctx, entity, partialTick);
-
- currentStack = entity.getItem();
- bakedModel = ItemModels.getModel(currentStack);
- var model = ItemModels.get(level, currentStack, ItemDisplayContext.GROUND);
- instances = new InstanceRecycler<>(() -> ctx.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, model)
- .createInstance());
-
- animate(partialTick);
- }
-
- public static boolean isSupported(ItemEntity entity) {
- return ItemModels.isSupported(entity.getItem());
- }
-
- @Override
- public void beginFrame(Context ctx) {
- if (!isVisible(ctx.frustum())) {
- return;
- }
-
- animate(ctx.partialTick());
- }
-
- private void animate(float partialTick) {
- pPoseStack.setIdentity();
- TransformStack.of(pPoseStack)
- .translate(getVisualPosition(partialTick));
-
- ItemStack itemstack = entity.getItem();
- if (!ItemStack.matches(itemstack, currentStack)) {
- instances.delete();
- currentStack = itemstack.copy();
- bakedModel = ItemModels.getModel(currentStack);
- var model = ItemModels.get(level, currentStack, ItemDisplayContext.GROUND);
- instances = new InstanceRecycler<>(() -> visualizationContext.instancerProvider()
- .instancer(InstanceTypes.TRANSFORMED, model)
- .createInstance());
- }
- instances.resetCount();
-
- int i = itemstack.isEmpty() ? 187 : Item.getId(itemstack.getItem()) + itemstack.getDamageValue();
- var random = RANDOM.get();
- random.setSeed(i);
- boolean flag = bakedModel.isGui3d();
- int j = this.getRenderAmount(itemstack);
- float f = 0.25F;
- float f1 = shouldBob() ? Mth.sin(((float) entity.getAge() + partialTick) / 10.0F + entity.bobOffs) * 0.1F + 0.1F : 0;
- float groundScaleX = bakedModel.getTransforms().ground.scale.y();
- float groundScaleY = bakedModel.getTransforms().ground.scale.y();
- float groundScaleZ = bakedModel.getTransforms().ground.scale.y();
- pPoseStack.translate(0.0F, f1 + 0.25F * groundScaleZ, 0.0F);
- float f3 = entity.getSpin(partialTick);
- pPoseStack.mulPose(Axis.YP.rotation(f3));
- if (!flag) {
- float f7 = -0.0F * (float) (j - 1) * 0.5F * groundScaleX;
- float f8 = -0.0F * (float) (j - 1) * 0.5F * groundScaleY;
- float f9 = -0.09375F * (float) (j - 1) * 0.5F * groundScaleZ;
- pPoseStack.translate(f7, f8, f9);
- }
-
- int light = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, entity.blockPosition()), level.getBrightness(LightLayer.SKY, entity.blockPosition()));
-
- for (int k = 0; k < j; ++k) {
- pPoseStack.pushPose();
- if (k > 0) {
- if (flag) {
- float f11 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F;
- float f13 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F;
- float f10 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F;
- pPoseStack.translate(shouldSpreadItems() ? f11 : 0, shouldSpreadItems() ? f13 : 0, shouldSpreadItems() ? f10 : 0);
- } else {
- float f12 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F;
- float f14 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F;
- pPoseStack.translate(shouldSpreadItems() ? f12 : 0, shouldSpreadItems() ? f14 : 0, 0.0D);
- }
- }
-
- instances.get()
- .setTransform(pPoseStack.last())
- .light(light)
- .setChanged();
- pPoseStack.popPose();
- if (!flag) {
- pPoseStack.translate(0.0, 0.0, 0.09375F * groundScaleZ);
- }
- }
-
- instances.discardExtra();
- }
-
- protected int getRenderAmount(ItemStack pStack) {
- int i = 1;
- if (pStack.getCount() > 48) {
- i = 5;
- } else if (pStack.getCount() > 32) {
- i = 4;
- } else if (pStack.getCount() > 16) {
- i = 3;
- } else if (pStack.getCount() > 1) {
- i = 2;
- }
-
- return i;
- }
-
- /**
- * @return If items should spread out when rendered in 3D
- */
- public boolean shouldSpreadItems() {
- return true;
- }
-
- /**
- * @return If items should have a bob effect
- */
- public boolean shouldBob() {
- return true;
- }
-
- @Override
- protected void _delete() {
- instances.delete();
- }
-
-}
diff --git a/common/src/vanillin/resources/vanillin.mixins.json b/common/src/vanillin/resources/vanillin.mixins.json
deleted file mode 100644
index 0b196dae8..000000000
--- a/common/src/vanillin/resources/vanillin.mixins.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "required" : true,
- "minVersion" : "0.8",
- "package" : "dev.engine_room.vanillin.mixin",
- "compatibilityLevel" : "JAVA_21",
- "refmap" : "vanillin.refmap.json",
- "client" : [
- "item.ItemOverridesAccessor"
- ],
- "injectors" : {
- "defaultRequire" : 1
- }
-}
diff --git a/docs/flywheel/api/stage/fragment.glsl b/docs/flywheel/api/stage/fragment.glsl
index e13ec6588..ffa82b5a1 100644
--- a/docs/flywheel/api/stage/fragment.glsl
+++ b/docs/flywheel/api/stage/fragment.glsl
@@ -12,7 +12,8 @@
/*const*/ vec4 flw_sampleColor;
-/*const*/ float flw_distance;
+/*const*/ float flw_sphericalDistance;
+/*const*/ float flw_cylindricalDistance;
vec4 flw_fragColor;
ivec2 flw_fragOverlay;
diff --git a/docs/flywheel/api/uniforms/fog.glsl b/docs/flywheel/api/uniforms/fog.glsl
index 73ce76546..e8965975d 100644
--- a/docs/flywheel/api/uniforms/fog.glsl
+++ b/docs/flywheel/api/uniforms/fog.glsl
@@ -1,3 +1,5 @@
vec4 flw_fogColor;
-vec2 flw_fogRange;
-int flw_fogShape;
+vec2 flw_fogEnvironmentalRange;
+vec2 flw_fogRenderDistanceRange;
+float flw_fogSkyEnd;
+float flw_fogCloudEnd;
diff --git a/docs/flywheel/api/uniforms/level.glsl b/docs/flywheel/api/uniforms/level.glsl
index ec8f29f66..c901a877c 100644
--- a/docs/flywheel/api/uniforms/level.glsl
+++ b/docs/flywheel/api/uniforms/level.glsl
@@ -12,10 +12,13 @@ float flw_timeOfDay;
uint flw_levelHasSkyLight;
float flw_sunAngle;
+float flw_moonAngle;
+float flw_starAngle;
float flw_moonBrightness;
/** There are normally only 8 moon phases. */
uint flw_moonPhase;
+float flw_starBrightness;
uint flw_isRaining;
float flw_rainLevel;
@@ -24,7 +27,7 @@ float flw_thunderLevel;
float flw_skyDarken;
-uint flw_constantAmbientLight;
+uint flw_cardinalLightType;
/** Use FLW_DIMENSION_* ids to determine the dimension. May eventually be implemented for custom dimensions. */
uint flw_dimension;
diff --git a/fabric/build.gradle.kts b/fabric/build.gradle.kts
index d0afd06e6..6b0493e1f 100644
--- a/fabric/build.gradle.kts
+++ b/fabric/build.gradle.kts
@@ -1,23 +1,19 @@
+import dev.engine_room.gradle.getExt
+
plugins {
- idea
- java
- `maven-publish`
- id("dev.architectury.loom")
- id("flywheel.subproject")
- id("flywheel.platform")
+ alias(libs.plugins.flywheel.gradle)
+ alias(libs.plugins.configure.base)
+ alias(libs.plugins.configure.fabric)
+ alias(libs.plugins.setup.repositories)
}
-val common = ":common"
+val common = projects.flywheelCommon.path
val commonProject = project(common)
-subproject.init("flywheel-fabric", "flywheel_group", "flywheel_version")
-
val api = sourceSets.create("api")
val lib = sourceSets.create("lib")
val backend = sourceSets.create("backend")
-val stubs = sourceSets.create("stubs")
val main = sourceSets.getByName("main")
-val testMod = sourceSets.create("testMod")
transitiveSourceSets {
compileClasspath = main.compileClasspath
@@ -41,77 +37,33 @@ transitiveSourceSets {
from(commonProject)
}
- sourceSet(stubs) {
- rootCompile()
-
- from(commonProject)
- }
sourceSet(main) {
- // Don't want stubs at runtime
- compileClasspath(stubs)
implementation(api, lib, backend)
bundleFrom(commonProject)
bundleOutput(api, lib, backend)
}
- sourceSet(testMod) {
- rootCompile()
- }
createCompileConfigurations()
}
-platform {
- setupLoomMod(api, lib, backend, main)
- setupLoomRuns()
- setupTestMod(testMod)
-}
-
-var flywheelVersion = "${property("flywheel_version")}+${property("minecraft_version")}"
-
-if (subproject.buildNumber != null) {
- flywheelVersion += ".build.${subproject.buildNumber}"
-}
+loom {
+ accessWidenerPath = file("src/main/resources/flywheel.accesswidener")
-val replaceProperties = listOf(
- "mod_license",
- "mod_sources",
- "mod_issues",
- "mod_homepage",
- "flywheel_id",
- "flywheel_name",
- "flywheel_description",
- "minecraft_semver_version_range",
- "fabric_api_version_range",
-).associateWith { property(it) as String }
- .plus("flywheel_version" to flywheelVersion)
-
-tasks.withType().configureEach {
- inputs.properties(replaceProperties)
-
- filesMatching(listOf("fabric.mod.json")) {
- expand(replaceProperties)
+ mods.getByName(getExt("mod_id")).apply {
+ sourceSet(api)
+ sourceSet(lib)
+ sourceSet(backend)
}
}
jarSets {
- mainSet.publishWithRemappedSources {
- artifactId = "flywheel-fabric-${property("artifact_minecraft_version")}"
- }
mainSet.outgoing("flywheel")
create("api", api, lib).apply {
addToAssemble()
- publishWithRemappedSources {
- artifactId = "flywheel-fabric-api-${property("artifact_minecraft_version")}"
- }
-
- configureJar {
- manifest {
- attributes("Fabric-Loom-Remap" to "true")
- }
- }
+ publish()
}
}
@@ -119,25 +71,16 @@ defaultPackageInfos {
sources(api, lib, backend, main)
}
-loom {
- mixin {
- useLegacyMixinAp = true
- add(main, "flywheel.refmap.json")
- add(backend, "backend-flywheel.refmap.json")
- }
-}
-
dependencies {
- modImplementation("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
- modApi("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}")
+ implementation(libs.fabric.loader)
+ api(libs.fabric.api)
- modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric")
- modCompileOnly("maven.modrinth:iris:${property("iris_version")}-fabric")
+ compileOnly(libs.sodium.fabric.api)
+ compileOnly(libs.iris.fabric)
"forApi"(project(path = common, configuration = "apiClasses"))
"forLib"(project(path = common, configuration = "libClasses"))
"forBackend"(project(path = common, configuration = "backendClasses"))
- "forStubs"(project(path = common, configuration = "stubsClasses"))
"forMain"(project(path = common, configuration = "mainClasses"))
"forLib"(project(path = common, configuration = "libResources"))
diff --git a/fabric/gradle.properties b/fabric/gradle.properties
deleted file mode 100644
index 6c5947614..000000000
--- a/fabric/gradle.properties
+++ /dev/null
@@ -1 +0,0 @@
-loom.platform = fabric
diff --git a/fabric/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java b/fabric/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java
deleted file mode 100644
index 7782a5d7d..000000000
--- a/fabric/src/backend/java/dev/engine_room/flywheel/backend/compile/FlwProgramsReloader.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package dev.engine_room.flywheel.backend.compile;
-
-import dev.engine_room.flywheel.backend.NoiseTextures;
-import dev.engine_room.flywheel.lib.util.ResourceUtil;
-import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.packs.resources.ResourceManager;
-
-public final class FlwProgramsReloader implements SimpleSynchronousResourceReloadListener {
- public static final FlwProgramsReloader INSTANCE = new FlwProgramsReloader();
-
- public static final ResourceLocation ID = ResourceUtil.rl("programs");
-
- private FlwProgramsReloader() {
- }
-
- @Override
- public void onResourceManagerReload(ResourceManager manager) {
- FlwPrograms.reload(manager);
- NoiseTextures.reload(manager);
- }
-
- @Override
- public ResourceLocation getFabricId() {
- return ID;
- }
-}
diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java
deleted file mode 100644
index 721c1bda9..000000000
--- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java
+++ /dev/null
@@ -1,131 +0,0 @@
-package dev.engine_room.flywheel.lib.model.baked;
-
-import java.util.Iterator;
-
-import org.jetbrains.annotations.Nullable;
-
-import com.mojang.blaze3d.vertex.BufferBuilder;
-import com.mojang.blaze3d.vertex.PoseStack;
-
-import dev.engine_room.flywheel.lib.model.SimpleModel;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.ItemBlockRenderTypes;
-import net.minecraft.client.renderer.RenderType;
-import net.minecraft.client.renderer.block.BlockRenderDispatcher;
-import net.minecraft.client.renderer.block.ModelBlockRenderer;
-import net.minecraft.client.renderer.texture.OverlayTexture;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.core.BlockPos;
-import net.minecraft.util.RandomSource;
-import net.minecraft.world.level.BlockAndTintGetter;
-import net.minecraft.world.level.block.RenderShape;
-import net.minecraft.world.level.block.state.BlockState;
-import net.minecraft.world.level.material.FluidState;
-
-final class BakedModelBufferer {
- private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
-
- private BakedModelBufferer() {
- }
-
- public static SimpleModel bufferModel(BakedModel model, BlockPos pos, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, BlockMaterialFunction blockMaterialFunction) {
- ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
- if (poseStack == null) {
- poseStack = objects.identityPoseStack;
- }
- RandomSource random = objects.random;
- FabricMeshEmitterManager emitters = objects.emitters;
-
- emitters.prepare(blockMaterialFunction);
-
- long seed = state.getSeed(pos);
-
- RenderType defaultLayer = ItemBlockRenderTypes.getChunkRenderType(state);
- boolean useAo = Minecraft.useAmbientOcclusion();
- // See ModelBlockRenderer#tesselateBlock
- boolean defaultAo = useAo && state.getLightEmission() == 0 && model.useAmbientOcclusion();
- model = emitters.prepareForModel(model, defaultLayer, useAo, defaultAo);
-
- poseStack.pushPose();
- Minecraft.getInstance()
- .getBlockRenderer()
- .getModelRenderer()
- .tesselateBlock(level, model, state, pos, poseStack, emitters, false, random, seed, OverlayTexture.NO_OVERLAY);
- poseStack.popPose();
-
- return emitters.end();
- }
-
- public static SimpleModel bufferBlocks(Iterator posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, BlockMaterialFunction blockMaterialFunction) {
- ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
- if (poseStack == null) {
- poseStack = objects.identityPoseStack;
- }
- RandomSource random = objects.random;
- FabricMeshEmitterManager emitters = objects.emitters;
- TransformingVertexConsumer transformingWrapper = objects.transformingWrapper;
-
- emitters.prepare(blockMaterialFunction);
-
- BlockRenderDispatcher renderDispatcher = Minecraft.getInstance()
- .getBlockRenderer();
- ModelBlockRenderer blockRenderer = renderDispatcher.getModelRenderer();
- ModelBlockRenderer.enableCaching();
-
- boolean useAo = Minecraft.useAmbientOcclusion();
-
- while (posIterator.hasNext()) {
- BlockPos pos = posIterator.next();
- BlockState state = level.getBlockState(pos);
-
- emitters.prepareForBlock();
-
- if (renderFluids) {
- FluidState fluidState = state.getFluidState();
-
- if (!fluidState.isEmpty()) {
- RenderType renderType = ItemBlockRenderTypes.getRenderLayer(fluidState);
-
- BufferBuilder bufferBuilder = emitters.getBuffer(renderType, true, false);
-
- if (bufferBuilder != null) {
- transformingWrapper.prepare(bufferBuilder, poseStack);
-
- poseStack.pushPose();
- poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF));
- renderDispatcher.renderLiquid(pos, level, transformingWrapper, state, fluidState);
- poseStack.popPose();
- }
- }
- }
-
- if (state.getRenderShape() == RenderShape.MODEL) {
- long seed = state.getSeed(pos);
- BakedModel model = renderDispatcher.getBlockModel(state);
-
- RenderType defaultLayer = ItemBlockRenderTypes.getChunkRenderType(state);
-
- // See ModelBlockRenderer#tesselateBlock
- boolean defaultAo = useAo && state.getLightEmission() == 0 && model.useAmbientOcclusion();
- model = emitters.prepareForModel(model, defaultLayer, useAo, defaultAo);
-
- poseStack.pushPose();
- poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
- blockRenderer.tesselateBlock(level, model, state, pos, poseStack, emitters, true, random, seed, OverlayTexture.NO_OVERLAY);
- poseStack.popPose();
- }
- }
-
- ModelBlockRenderer.clearCache();
- transformingWrapper.clear();
- return emitters.end();
- }
-
- private static class ThreadLocalObjects {
- public final PoseStack identityPoseStack = new PoseStack();
- public final RandomSource random = RandomSource.createNewThreadLocalInstance();
-
- public final FabricMeshEmitterManager emitters = new FabricMeshEmitterManager();
- public final TransformingVertexConsumer transformingWrapper = new TransformingVertexConsumer();
- }
-}
diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java
new file mode 100644
index 000000000..d05c9b551
--- /dev/null
+++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java
@@ -0,0 +1,154 @@
+package dev.engine_room.flywheel.lib.model.baked;
+
+import java.util.Iterator;
+
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.Nullable;
+
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.PoseStack;
+
+import dev.engine_room.flywheel.lib.model.SimpleModel;
+import net.fabricmc.fabric.api.client.renderer.v1.Renderer;
+import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadEmitter;
+import net.fabricmc.fabric.api.client.renderer.v1.render.AltModelBlockRenderer;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.color.block.BlockColors;
+import net.minecraft.client.renderer.block.BlockAndTintGetter;
+import net.minecraft.client.renderer.block.BlockModelLighter;
+import net.minecraft.client.renderer.block.FluidRenderer;
+import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
+import net.minecraft.client.renderer.state.GameRenderState;
+import net.minecraft.client.renderer.texture.OverlayTexture;
+import net.minecraft.client.resources.model.ModelManager;
+import net.minecraft.core.BlockPos;
+import net.minecraft.world.level.block.RenderShape;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.material.FluidState;
+
+@ApiStatus.Internal
+public final class BlockStateModelBufferer {
+ private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
+
+ private BlockStateModelBufferer() {
+ }
+
+ public static SimpleModel bufferModel(BlockStateModel model, BlockPos pos, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, BlockMaterialFunction blockMaterialFunction) {
+ ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
+ if (poseStack == null) {
+ poseStack = objects.identityPoseStack;
+ }
+ FabricMeshEmitterManager emitters = objects.emitters;
+
+ emitters.prepare(blockMaterialFunction);
+
+ long seed = state.getSeed(pos);
+
+ Minecraft minecraft = Minecraft.getInstance();
+ GameRenderState gameRenderState = minecraft.gameRenderer.getGameRenderState();
+ BlockColors blockColors = minecraft.getBlockColors();
+
+ // See ModelBlockRenderer#tesselateBlock
+ boolean useAo = gameRenderState.optionsRenderState.ambientOcclusion;
+ boolean defaultAo = useAo && state.getLightEmission() == 0;
+ emitters.prepareForModel(useAo, defaultAo);
+
+ AltModelBlockRenderer altModelBlockRenderer = Renderer.get().altModelBlockRenderer(useAo, true, blockColors);
+
+ PoseStack finalPoseStack = poseStack;
+ QuadEmitter quadEmitter = Renderer.get().quadEmitter((quad) -> {
+ finalPoseStack.pushPose();
+ ChunkSectionLayer layer = quad.chunkLayer();
+ FabricMeshEmitter emitter = emitters.getEmitter(layer);
+ emitters.prepareForGeometry(quad);
+ quad.buffer(OverlayTexture.NO_OVERLAY, finalPoseStack.last(), emitter);
+ finalPoseStack.popPose();
+ });
+
+ altModelBlockRenderer.tesselateBlock(quadEmitter, 0, 0, 0, level, pos, state, model, seed);
+
+ return emitters.end();
+ }
+
+ public static SimpleModel bufferBlocks(Iterator posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, BlockMaterialFunction blockMaterialFunction) {
+ ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
+ if (poseStack == null) {
+ poseStack = objects.identityPoseStack;
+ }
+ FabricMeshEmitterManager emitters = objects.emitters;
+ TransformingVertexConsumer transformingWrapper = objects.transformingWrapper;
+
+ emitters.prepare(blockMaterialFunction);
+
+ BlockModelLighter.enableCaching();
+
+ Minecraft minecraft = Minecraft.getInstance();
+ ModelManager modelManager = minecraft.getModelManager();
+ GameRenderState gameRenderState = minecraft.gameRenderer.getGameRenderState();
+ boolean useAo = gameRenderState.optionsRenderState.ambientOcclusion;
+ BlockColors blockColors = minecraft.getBlockColors();
+
+ AltModelBlockRenderer altModelBlockRenderer = Renderer.get().altModelBlockRenderer(useAo, true, blockColors);
+ FluidRenderer fluidRenderer = new FluidRenderer(modelManager.getFluidStateModelSet());
+
+ while (posIterator.hasNext()) {
+ BlockPos pos = posIterator.next();
+ BlockState state = level.getBlockState(pos);
+
+ emitters.prepareForBlock();
+
+ if (renderFluids) {
+ FluidState fluidState = state.getFluidState();
+
+ if (!fluidState.isEmpty()) {
+ poseStack.pushPose();
+ poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF));
+ PoseStack finalPoseStack = poseStack;
+ fluidRenderer.tesselate(level, pos, layer -> {
+ BufferBuilder bufferBuilder = emitters.getEmitter(layer).getBuffer(true, false);
+
+ if (bufferBuilder != null) {
+ transformingWrapper.prepare(bufferBuilder, finalPoseStack);
+ return transformingWrapper;
+ }
+
+ return EmptyVertexConsumer.INSTANCE;
+ }, state, fluidState);
+ poseStack.popPose();
+ }
+ }
+
+ if (state.getRenderShape() == RenderShape.MODEL) {
+ long seed = state.getSeed(pos);
+ BlockStateModel model = modelManager.getBlockStateModelSet().get(state);
+
+ // See ModelBlockRenderer#tesselateBlock
+ boolean defaultAo = useAo && state.getLightEmission() == 0;
+ emitters.prepareForModel(useAo, defaultAo);
+
+ PoseStack finalPoseStack = poseStack;
+ QuadEmitter quadEmitter = Renderer.get().quadEmitter((quad) -> {
+ finalPoseStack.pushPose();
+ ChunkSectionLayer layer = quad.chunkLayer();
+ FabricMeshEmitter emitter = emitters.getEmitter(layer);
+ emitters.prepareForGeometry(quad);
+ quad.buffer(OverlayTexture.NO_OVERLAY, finalPoseStack.last(), emitter);
+ finalPoseStack.popPose();
+ });
+ altModelBlockRenderer.tesselateBlock(quadEmitter, pos.getX(), pos.getY(), pos.getZ(), level, pos, state, model, seed);
+ }
+ }
+
+ BlockModelLighter.clearCache();
+ transformingWrapper.clear();
+ return emitters.end();
+ }
+
+ private static class ThreadLocalObjects {
+ public final PoseStack identityPoseStack = new PoseStack();
+
+ public final FabricMeshEmitterManager emitters = new FabricMeshEmitterManager();
+ public final TransformingVertexConsumer transformingWrapper = new TransformingVertexConsumer();
+ }
+}
diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitter.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitter.java
new file mode 100644
index 000000000..57a0473f6
--- /dev/null
+++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitter.java
@@ -0,0 +1,122 @@
+package dev.engine_room.flywheel.lib.model.baked;
+
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.PoseStack.Pose;
+import com.mojang.blaze3d.vertex.QuadInstance;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
+import net.minecraft.client.resources.model.geometry.BakedQuad;
+
+import org.jetbrains.annotations.ApiStatus;
+
+@ApiStatus.Internal
+public class FabricMeshEmitter extends MeshEmitter {
+ private boolean shade;
+ private boolean ao;
+
+ FabricMeshEmitter(ByteBufferBuilderStack byteBufferBuilderStack, ChunkSectionLayer chunkSectionLayer) {
+ super(byteBufferBuilderStack, chunkSectionLayer);
+ }
+
+ public void prepareForGeometry(boolean shade, boolean ao) {
+ this.shade = shade;
+ this.ao = ao;
+ }
+
+ @Override
+ public VertexConsumer addVertex(float x, float y, float z) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.addVertex(x, y, z);
+ }
+ return this;
+ }
+
+ @Override
+ public VertexConsumer setColor(int red, int green, int blue, int alpha) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.setColor(red, green, blue, alpha);
+ }
+ return this;
+ }
+
+ @Override
+ public VertexConsumer setColor(int color) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.setColor(color);
+ }
+ return this;
+ }
+
+ @Override
+ public VertexConsumer setUv(float u, float v) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.setUv(u, v);
+ }
+ return this;
+ }
+
+ @Override
+ public VertexConsumer setUv1(int u, int v) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.setUv1(u, v);
+ }
+ return this;
+ }
+
+ @Override
+ public VertexConsumer setUv2(int u, int v) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.setUv2(u, v);
+ }
+ return this;
+ }
+
+ @Override
+ public VertexConsumer setNormal(float x, float y, float z) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.setNormal(x, y, z);
+ }
+ return this;
+ }
+
+ @Override
+ public VertexConsumer setLineWidth(float width) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.setLineWidth(width);
+ }
+ return this;
+ }
+
+ @Override
+ public void addVertex(float x, float y, float z, int color, float u, float v, int packedOverlay, int packedLight, float normalX, float normalY, float normalZ) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.addVertex(x, y, z, color, u, v, packedOverlay, packedLight, normalX, normalY, normalZ);
+ }
+ }
+
+ @Override
+ public void putBakedQuad(Pose pose, BakedQuad quad, QuadInstance instance) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.putBakedQuad(pose, quad, instance);
+ }
+ }
+
+ @Override
+ public void putBlockBakedQuad(float x, float y, float z, BakedQuad quad, QuadInstance instance) {
+ BufferBuilder bufferBuilder = getBuffer(shade, ao);
+ if (bufferBuilder != null) {
+ bufferBuilder.putBlockBakedQuad(x, y, z, quad, instance);
+ }
+ }
+}
diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitterManager.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitterManager.java
index 2f0a40f32..cfbaee447 100644
--- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitterManager.java
+++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricMeshEmitterManager.java
@@ -1,154 +1,31 @@
package dev.engine_room.flywheel.lib.model.baked;
-import java.util.function.Supplier;
-
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.UnknownNullability;
-
-import com.mojang.blaze3d.vertex.BufferBuilder;
-import com.mojang.blaze3d.vertex.PoseStack;
-import com.mojang.blaze3d.vertex.VertexConsumer;
-
-import dev.engine_room.flywheel.lib.model.SimpleModel;
-import net.fabricmc.fabric.api.renderer.v1.material.BlendMode;
-import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial;
-import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel;
-import net.fabricmc.fabric.api.renderer.v1.render.RenderContext;
+import net.fabricmc.fabric.api.client.renderer.v1.mesh.QuadView;
import net.fabricmc.fabric.api.util.TriState;
-import net.minecraft.client.renderer.RenderType;
-import net.minecraft.client.renderer.block.model.BakedQuad;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.core.BlockPos;
-import net.minecraft.util.RandomSource;
-import net.minecraft.world.level.BlockAndTintGetter;
-import net.minecraft.world.level.block.state.BlockState;
-class FabricMeshEmitterManager extends MeshEmitterManager implements VertexConsumer {
- private final WrapperModel wrapperModel = new WrapperModel();
+import org.jetbrains.annotations.ApiStatus;
- @UnknownNullability
- private RenderType defaultLayer;
+@ApiStatus.Internal
+public class FabricMeshEmitterManager extends MeshEmitterManager {
private boolean useAo;
private boolean defaultAo;
- @Nullable
- private BufferBuilder currentDelegate;
FabricMeshEmitterManager() {
- super(MeshEmitter::new);
+ super(FabricMeshEmitter::new);
}
- public BakedModel prepareForModel(BakedModel model, RenderType defaultLayer, boolean useAo, boolean defaultAo) {
- this.defaultLayer = defaultLayer;
+ public void prepareForModel(boolean useAo, boolean defaultAo) {
this.useAo = useAo;
this.defaultAo = defaultAo;
- wrapperModel.setWrapped(model);
- return wrapperModel;
- }
-
- @Override
- public SimpleModel end() {
- wrapperModel.setWrapped(null);
- return super.end();
}
- private void prepareForGeometry(RenderMaterial material) {
- BlendMode blendMode = material.blendMode();
- RenderType layer = blendMode == BlendMode.DEFAULT ? defaultLayer : blendMode.blockRenderLayer;
- boolean shade = !material.disableDiffuse();
- TriState aoMode = material.ambientOcclusion();
+ public void prepareForGeometry(QuadView quad) {
+ boolean shade = quad.diffuseShade();
+ TriState aoMode = quad.ambientOcclusion();
boolean ao = useAo && aoMode.orElse(defaultAo);
- currentDelegate = getBuffer(layer, shade, ao);
- }
-
- @Override
- public VertexConsumer addVertex(float x, float y, float z) {
- if (currentDelegate != null) {
- currentDelegate.addVertex(x, y, z);
- }
- return this;
- }
-
- @Override
- public VertexConsumer setColor(int red, int green, int blue, int alpha) {
- if (currentDelegate != null) {
- currentDelegate.setColor(red, green, blue, alpha);
- }
- return this;
- }
-
- @Override
- public VertexConsumer setUv(float u, float v) {
- if (currentDelegate != null) {
- currentDelegate.setUv(u, v);
- }
- return this;
- }
-
- @Override
- public VertexConsumer setUv1(int u, int v) {
- if (currentDelegate != null) {
- currentDelegate.setUv1(u, v);
- }
- return this;
- }
-
- @Override
- public VertexConsumer setUv2(int u, int v) {
- if (currentDelegate != null) {
- currentDelegate.setUv2(u, v);
- }
- return this;
- }
-
- @Override
- public VertexConsumer setNormal(float x, float y, float z) {
- if (currentDelegate != null) {
- currentDelegate.setNormal(x, y, z);
- }
- return this;
- }
-
- @Override
- public void addVertex(float x, float y, float z, int color, float u, float v, int packedOverlay, int packedLight, float normalX, float normalY, float normalZ) {
- if (currentDelegate != null) {
- currentDelegate.addVertex(x, y, z, color, u, v, packedOverlay, packedLight, normalX, normalY, normalZ);
- }
- }
-
- @Override
- public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, float alpha, int packedLight, int packedOverlay) {
- if (currentDelegate != null) {
- currentDelegate.putBulkData(pose, quad, red, green, blue, alpha, packedLight, packedOverlay);
- }
- }
-
- @Override
- public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightness, float red, float green, float blue, float alpha, int[] lightmap, int packedOverlay, boolean readAlpha) {
- if (currentDelegate != null) {
- currentDelegate.putBulkData(pose, quad, brightness, red, green, blue, alpha, lightmap, packedOverlay, readAlpha);
- }
- }
-
- private class WrapperModel extends ForwardingBakedModel {
- private final RenderContext.QuadTransform quadTransform = quad -> {
- FabricMeshEmitterManager.this.prepareForGeometry(quad.material());
- return true;
- };
-
- public void setWrapped(@Nullable BakedModel wrapped) {
- this.wrapped = wrapped;
- }
-
- @Override
- public boolean isVanillaAdapter() {
- return false;
- }
- @Override
- public void emitBlockQuads(BlockAndTintGetter level, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) {
- context.pushTransform(quadTransform);
- super.emitBlockQuads(level, state, pos, randomSupplier, context);
- context.popTransform();
+ for (FabricMeshEmitter emitter : emitterMap.values()) {
+ emitter.prepareForGeometry(shade, ao);
}
}
}
diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricPartialModel.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricPartialModel.java
new file mode 100644
index 000000000..34030f9a6
--- /dev/null
+++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricPartialModel.java
@@ -0,0 +1,77 @@
+package dev.engine_room.flywheel.lib.model.baked;
+
+import java.util.concurrent.ConcurrentMap;
+
+import org.jetbrains.annotations.ApiStatus;
+
+import com.google.common.collect.MapMaker;
+
+import dev.engine_room.flywheel.lib.util.IdentifierUtil;
+import net.fabricmc.fabric.api.client.model.loading.v1.ExtraModelKey;
+import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
+import net.fabricmc.fabric.api.client.model.loading.v1.UnbakedExtraModel;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.renderer.block.dispatch.BlockModelRotation;
+import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
+import net.minecraft.client.renderer.block.dispatch.SingleVariant;
+import net.minecraft.client.resources.model.ModelBaker;
+import net.minecraft.client.resources.model.ModelManager;
+import net.minecraft.client.resources.model.SimpleModelWrapper;
+import net.minecraft.resources.Identifier;
+import net.minecraft.server.packs.resources.ResourceManager;
+import net.minecraft.server.packs.resources.ResourceManagerReloadListener;
+
+import org.jspecify.annotations.NullMarked;
+
+@ApiStatus.Internal
+public class FabricPartialModel extends PartialModel {
+ private static final ConcurrentMap ALL = new MapMaker().weakValues().makeMap();
+
+ private final ExtraModelKey key;
+
+ public FabricPartialModel(Identifier modelId) {
+ super(modelId);
+ key = ExtraModelKey.create(modelId::toString);
+ }
+
+ public static FabricPartialModel of(Identifier modelId) {
+ return ALL.computeIfAbsent(modelId, FabricPartialModel::new);
+ }
+
+ public static void registerAll(ModelLoadingPlugin.Context ctx) {
+ for (FabricPartialModel partial : ALL.values()) {
+ ctx.addModel(partial.key, partial.new Unbaked());
+ }
+ }
+
+ public static void refreshAll(ModelManager modelManager) {
+ for (FabricPartialModel partial : ALL.values()) {
+ partial.blockStateModel = modelManager.getModel(partial.key);
+ }
+ }
+
+ @NullMarked
+ private class Unbaked implements UnbakedExtraModel {
+ @Override
+ public BlockStateModel bake(ModelBaker baker) {
+ return new SingleVariant(SimpleModelWrapper.bake(baker, modelId, BlockModelRotation.IDENTITY));
+ }
+
+ @Override
+ public void resolveDependencies(Resolver resolver) {
+ resolver.markDependency(modelId);
+ }
+ }
+
+ @NullMarked
+ public static class ResourceReloadListener implements ResourceManagerReloadListener {
+ public static final Identifier ID = IdentifierUtil.id("partial_models");
+
+ public static final ResourceReloadListener INSTANCE = new ResourceReloadListener();
+
+ @Override
+ public void onResourceManagerReload(ResourceManager resourceManager) {
+ refreshAll(Minecraft.getInstance().getModelManager());
+ }
+ }
+}
diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricSinglePosVirtualBlockGetter.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricSinglePosVirtualBlockGetter.java
index 7a860daf3..462c4642e 100644
--- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricSinglePosVirtualBlockGetter.java
+++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/FabricSinglePosVirtualBlockGetter.java
@@ -2,7 +2,7 @@
import java.util.function.ToIntFunction;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntity;
diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java
index 4a0bcc4dd..741aa54c3 100644
--- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java
+++ b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java
@@ -11,13 +11,13 @@ public final class ModelBuilderImpl {
private ModelBuilderImpl() {
}
- public static SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) {
+ public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
BlockState blockState = builder.level.getBlockState(builder.pos);
- return BakedModelBufferer.bufferModel(builder.bakedModel, builder.pos, builder.level, blockState, builder.poseStack, builder.materialFunc);
+ return BlockStateModelBufferer.bufferModel(builder.blockModel, builder.pos, builder.level, blockState, builder.poseStack, builder.materialFunc);
}
- public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
- return BakedModelBufferer.bufferBlocks(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, builder.materialFunc);
+ public static SimpleModel buildLevelModelBuilder(LevelModelBuilder builder) {
+ return BlockStateModelBufferer.bufferBlocks(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, builder.materialFunc);
}
}
diff --git a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java b/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java
deleted file mode 100644
index 62fb40ac3..000000000
--- a/fabric/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java
+++ /dev/null
@@ -1,56 +0,0 @@
-package dev.engine_room.flywheel.lib.model.baked;
-
-import java.util.List;
-
-import org.jetbrains.annotations.ApiStatus;
-
-import dev.engine_room.flywheel.lib.util.ResourceUtil;
-import net.fabricmc.fabric.api.resource.ResourceReloadListenerKeys;
-import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.resources.model.ModelManager;
-import net.minecraft.resources.ResourceLocation;
-import net.minecraft.server.packs.resources.ResourceManager;
-
-@ApiStatus.Internal
-public final class PartialModelEventHandler {
- private PartialModelEventHandler() {
- }
-
- public static ResourceLocation[] onRegisterAdditional() {
- return PartialModel.ALL.keySet().toArray(ResourceLocation[]::new);
- }
-
- public static void onBakingCompleted(ModelManager manager) {
- PartialModel.populateOnInit = true;
-
- for (PartialModel partial : PartialModel.ALL.values()) {
- partial.bakedModel = manager.getModel(partial.modelLocation());
- }
- }
-
- public static final class ReloadListener implements SimpleSynchronousResourceReloadListener {
- public static final ReloadListener INSTANCE = new ReloadListener();
-
- public static final ResourceLocation ID = ResourceUtil.rl("partial_models");
- public static final List DEPENDENCIES = List.of(ResourceReloadListenerKeys.MODELS);
-
- private ReloadListener() {
- }
-
- @Override
- public void onResourceManagerReload(ResourceManager resourceManager) {
- onBakingCompleted(Minecraft.getInstance().getModelManager());
- }
-
- @Override
- public ResourceLocation getFabricId() {
- return ID;
- }
-
- @Override
- public List getFabricDependencies() {
- return DEPENDENCIES;
- }
- }
-}
diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/FabricFlwConfig.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/FabricFlwConfig.java
index 0e566a409..8f5769366 100644
--- a/fabric/src/main/java/dev/engine_room/flywheel/impl/FabricFlwConfig.java
+++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/FabricFlwConfig.java
@@ -18,8 +18,8 @@
import dev.engine_room.flywheel.backend.FlwBackend;
import dev.engine_room.flywheel.backend.compile.LightSmoothness;
import net.fabricmc.loader.api.FabricLoader;
-import net.minecraft.ResourceLocationException;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.IdentifierException;
+import net.minecraft.resources.Identifier;
import net.minecraft.util.Mth;
public class FabricFlwConfig implements FlwConfig {
@@ -122,11 +122,11 @@ private void readBackend(JsonObject object) {
}
try {
- this.backend = Backend.REGISTRY.getOrThrow(ResourceLocation.parse(value));
+ this.backend = Backend.REGISTRY.getOrThrow(Identifier.parse(value));
useDefaultBackend = false;
return;
- } catch (ResourceLocationException e) {
- msg = "'backend' value '" + value + "' is not a valid resource location";
+ } catch (IdentifierException e) {
+ msg = "'backend' value '" + value + "' is not a valid resource id";
} catch (IllegalArgumentException e) {
msg = "Backend with ID '" + value + "' is not registered";
} catch (Exception e) {
diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java
index 7a0cee7b4..4c8587f51 100644
--- a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java
+++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwCommands.java
@@ -13,10 +13,13 @@
import dev.engine_room.flywheel.backend.compile.PipelineCompiler;
import dev.engine_room.flywheel.backend.engine.uniform.DebugMode;
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
-import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
+import net.fabricmc.fabric.api.client.command.v2.ClientCommands;
import net.fabricmc.fabric.api.client.command.v2.FabricClientCommandSource;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.CommandBuildContext;
+import net.minecraft.commands.CommandSource;
+import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
import net.minecraft.commands.arguments.coordinates.Coordinates;
import net.minecraft.core.BlockPos;
@@ -28,9 +31,9 @@ private FlwCommands() {
}
public static void registerClientCommands(CommandDispatcher dispatcher, CommandBuildContext buildContext) {
- LiteralArgumentBuilder command = ClientCommandManager.literal("flywheel");
+ LiteralArgumentBuilder command = ClientCommands.literal("flywheel");
- command.then(ClientCommandManager.literal("backend")
+ command.then(ClientCommands.literal("backend")
.executes(context -> {
Backend backend = BackendManager.currentBackend();
String idStr = Backend.REGISTRY.getIdOrThrow(backend)
@@ -38,7 +41,7 @@ public static void registerClientCommands(CommandDispatcher {
FabricFlwConfig.INSTANCE.backend = BackendManager.offBackend();
FabricFlwConfig.INSTANCE.useDefaultBackend = true;
@@ -53,7 +56,7 @@ public static void registerClientCommands(CommandDispatcher {
Backend requestedBackend = context.getArgument("id", Backend.class);
FabricFlwConfig.INSTANCE.backend = requestedBackend;
@@ -76,7 +79,7 @@ public static void registerClientCommands(CommandDispatcher {
if (FabricFlwConfig.INSTANCE.limitUpdates) {
context.getSource().sendFeedback(Component.translatable("command.flywheel.limit_updates.get.on"));
@@ -85,7 +88,7 @@ public static void registerClientCommands(CommandDispatcher {
FabricFlwConfig.INSTANCE.limitUpdates = true;
FabricFlwConfig.INSTANCE.save();
@@ -93,7 +96,7 @@ public static void registerClientCommands(CommandDispatcher {
FabricFlwConfig.INSTANCE.limitUpdates = false;
FabricFlwConfig.INSTANCE.save();
@@ -102,8 +105,8 @@ public static void registerClientCommands(CommandDispatcher {
var oldValue = FabricFlwConfig.INSTANCE.backendConfig.lightSmoothness;
var newValue = context.getArgument("mode", LightSmoothness.class);
@@ -122,11 +125,11 @@ public static void registerClientCommands(CommandDispatcher createDebugCommand() {
- var debug = ClientCommandManager.literal("debug");
+ var debug = ClientCommands.literal("debug");
- debug.then(ClientCommandManager.literal("crumbling")
- .then(ClientCommandManager.argument("pos", BlockPosArgument.blockPos())
- .then(ClientCommandManager.argument("stage", IntegerArgumentType.integer(0, 9))
+ debug.then(ClientCommands.literal("crumbling")
+ .then(ClientCommands.argument("pos", BlockPosArgument.blockPos())
+ .then(ClientCommands.argument("stage", IntegerArgumentType.integer(0, 9))
.executes(context -> {
Entity executor = context.getSource()
.getEntity();
@@ -144,51 +147,51 @@ private static LiteralArgumentBuilder createDebugComm
return Command.SINGLE_SUCCESS;
}))));
- debug.then(ClientCommandManager.literal("shader")
- .then(ClientCommandManager.argument("mode", DebugModeArgument.INSTANCE)
+ debug.then(ClientCommands.literal("shader")
+ .then(ClientCommands.argument("mode", DebugModeArgument.INSTANCE)
.executes(context -> {
DebugMode mode = context.getArgument("mode", DebugMode.class);
FrameUniforms.debugMode(mode);
return Command.SINGLE_SUCCESS;
})));
- debug.then(ClientCommandManager.literal("frustum")
- .then(ClientCommandManager.literal("capture")
+ debug.then(ClientCommands.literal("frustum")
+ .then(ClientCommands.literal("capture")
.executes(context -> {
FrameUniforms.captureFrustum();
return Command.SINGLE_SUCCESS;
}))
- .then(ClientCommandManager.literal("unpause")
+ .then(ClientCommands.literal("unpause")
.executes(context -> {
FrameUniforms.unpauseFrustum();
return Command.SINGLE_SUCCESS;
})));
- debug.then(ClientCommandManager.literal("lightSections")
- .then(ClientCommandManager.literal("on")
+ debug.then(ClientCommands.literal("lightSections")
+ .then(ClientCommands.literal("on")
.executes(context -> {
BackendDebugFlags.LIGHT_STORAGE_VIEW = true;
return Command.SINGLE_SUCCESS;
}))
- .then(ClientCommandManager.literal("off")
+ .then(ClientCommands.literal("off")
.executes(context -> {
BackendDebugFlags.LIGHT_STORAGE_VIEW = false;
return Command.SINGLE_SUCCESS;
})));
- debug.then(ClientCommandManager.literal("pauseUpdates")
- .then(ClientCommandManager.literal("on")
+ debug.then(ClientCommands.literal("pauseUpdates")
+ .then(ClientCommands.literal("on")
.executes(context -> {
ImplDebugFlags.PAUSE_UPDATES = true;
return Command.SINGLE_SUCCESS;
}))
- .then(ClientCommandManager.literal("off")
+ .then(ClientCommands.literal("off")
.executes(context -> {
ImplDebugFlags.PAUSE_UPDATES = false;
return Command.SINGLE_SUCCESS;
})));
- debug.then(ClientCommandManager.literal("info")
+ debug.then(ClientCommands.literal("info")
.executes(context -> {
context.getSource()
.sendFeedback(FlwDebugInfo.getDebugCommandInfo());
@@ -200,6 +203,9 @@ private static LiteralArgumentBuilder createDebugComm
// Client version of BlockPosArgument.getBlockPos
private static BlockPos getBlockPos(CommandContext context, String name) {
- return context.getArgument(name, Coordinates.class).getBlockPos(context.getSource().getPlayer().createCommandSourceStack());
+ FabricClientCommandSource clientSource = context.getSource();
+ LocalPlayer player = clientSource.getPlayer();
+ CommandSourceStack commandSourceStack = new CommandSourceStack(CommandSource.NULL, clientSource.getPosition(), clientSource.getRotation(), null, clientSource.permissions(), player.getPlainTextName(), player.getDisplayName(), null, player);
+ return context.getArgument(name, Coordinates.class).getBlockPos(commandSourceStack);
}
}
diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java
index 733d53425..0c977a490 100644
--- a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java
+++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java
@@ -1,30 +1,27 @@
package dev.engine_room.flywheel.impl;
-import org.jetbrains.annotations.UnknownNullability;
-
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
import dev.engine_room.flywheel.lib.model.SimpleModel;
-import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
+import dev.engine_room.flywheel.lib.model.baked.FabricPartialModel;
+import dev.engine_room.flywheel.lib.model.baked.LevelModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.ModelBuilderImpl;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.client.resources.model.ModelManager;
-import net.minecraft.resources.ResourceLocation;
+import dev.engine_room.flywheel.lib.model.baked.PartialModel;
+import net.minecraft.resources.Identifier;
public class FlwLibXplatImpl implements FlwLibXplat {
@Override
- @UnknownNullability
- public BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location) {
- return modelManager.getModel(location);
+ public PartialModel createPartialModel(Identifier modelId) {
+ return FabricPartialModel.of(modelId);
}
@Override
- public SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) {
- return ModelBuilderImpl.buildBakedModelBuilder(builder);
+ public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
+ return ModelBuilderImpl.buildBlockModelBuilder(builder);
}
@Override
- public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
- return ModelBuilderImpl.buildBlockModelBuilder(builder);
+ public SimpleModel buildLevelModelBuilder(LevelModelBuilder builder) {
+ return ModelBuilderImpl.buildLevelModelBuilder(builder);
}
}
diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlywheelFabric.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlywheelFabric.java
index 3a4ce1c91..e4f0ad394 100644
--- a/fabric/src/main/java/dev/engine_room/flywheel/impl/FlywheelFabric.java
+++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/FlywheelFabric.java
@@ -8,19 +8,24 @@
import dev.engine_room.flywheel.backend.compile.FlwProgramsReloader;
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
import dev.engine_room.flywheel.impl.mixin.fabric.ArgumentTypeInfosAccessor;
+import dev.engine_room.flywheel.impl.task.FlwTaskExecutor;
import dev.engine_room.flywheel.impl.visualization.VisualizationEventHandler;
-import dev.engine_room.flywheel.lib.model.baked.PartialModelEventHandler;
+import dev.engine_room.flywheel.lib.model.baked.FabricPartialModel;
+import dev.engine_room.flywheel.lib.util.IdentifierUtil;
import dev.engine_room.flywheel.lib.util.RendererReloadCache;
import dev.engine_room.flywheel.lib.util.ResourceReloadHolder;
import net.fabricmc.api.ClientModInitializer;
import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientEntityEvents;
+import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents;
import net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin;
-import net.fabricmc.fabric.api.resource.ResourceManagerHelper;
+import net.fabricmc.fabric.api.resource.v1.ResourceLoader;
+import net.fabricmc.fabric.api.resource.v1.reloader.ResourceReloaderKeys;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.fabricmc.loader.api.Version;
+import net.minecraft.client.gui.components.debug.DebugScreenEntries;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.server.packs.PackType;
@@ -41,6 +46,8 @@ public void onInitializeClient() {
}
private static void setupImpl() {
+ ClientLifecycleEvents.CLIENT_STOPPING.register(_ -> FlwTaskExecutor.get().shutdown());
+
ReloadLevelRendererCallback.EVENT.register(BackendManagerImpl::onReloadLevelRenderer);
// This Fabric event runs slightly later than the Forge event Flywheel uses, but it shouldn't make a difference.
@@ -57,6 +64,8 @@ private static void setupImpl() {
ClientCommandRegistrationCallback.EVENT.register(FlwCommands::registerClientCommands);
+ DebugScreenEntries.register(FlwDebugInfo.FlwDebugEntry.ID, new FlwDebugInfo.FlwDebugEntry());
+
EndClientResourceReloadCallback.EVENT.register((minecraft, resourceManager, initialReload, error) ->
BackendManagerImpl.onEndClientResourceReload(error.isPresent()));
@@ -72,16 +81,15 @@ private static void setupLib() {
ReloadLevelRendererCallback.EVENT.register(level -> RendererReloadCache.onReloadLevelRenderer());
EndClientResourceReloadCallback.EVENT.register((minecraft, resourceManager, initialReload, error) -> ResourceReloadHolder.onEndClientResourceReload());
- ModelLoadingPlugin.register(ctx -> {
- ctx.addModels(PartialModelEventHandler.onRegisterAdditional());
- });
- ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(PartialModelEventHandler.ReloadListener.INSTANCE);
+ ModelLoadingPlugin.register(FabricPartialModel::registerAll);
+ ResourceLoader.get(PackType.CLIENT_RESOURCES).registerReloadListener(FabricPartialModel.ResourceReloadListener.ID, FabricPartialModel.ResourceReloadListener.INSTANCE);
+ ResourceLoader.get(PackType.CLIENT_RESOURCES).addListenerOrdering(ResourceReloaderKeys.Client.MODELS, FabricPartialModel.ResourceReloadListener.ID);
}
private static void setupBackend() {
ReloadLevelRendererCallback.EVENT.register(level -> Uniforms.onReloadLevelRenderer());
- ResourceManagerHelper.get(PackType.CLIENT_RESOURCES).registerReloadListener(FlwProgramsReloader.INSTANCE);
+ ResourceLoader.get(PackType.CLIENT_RESOURCES).registerReloadListener(FlwProgramsReloader.ID, FlwProgramsReloader.INSTANCE);
}
public static Version version() {
diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java
index dcab8eeec..ebef5304e 100644
--- a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java
+++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java
@@ -31,13 +31,13 @@ abstract class MinecraftMixin {
FabricFlwConfig.INSTANCE.load();
}
- @Inject(method = "method_53522", at = @At("HEAD"))
+ @Inject(method = "lambda$new$4", at = @At("HEAD"))
private void flywheel$onEndInitialResourceReload(@Coerce Object gameLoadCookie, Optional error, CallbackInfo ci) {
EndClientResourceReloadCallback.EVENT.invoker()
.onEndClientResourceReload((Minecraft) (Object) this, resourceManager, true, error);
}
- @Inject(method = "method_24228", at = @At("HEAD"))
+ @Inject(method = "lambda$reloadResourcePacks$0", at = @At("HEAD"))
private void flywheel$onEndManualResourceReload(boolean recovery, @Coerce Object gameLoadCookie, CompletableFuture future,
Optional error, CallbackInfo ci) {
EndClientResourceReloadCallback.EVENT.invoker()
diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/DebugScreenOverlayMixin.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/DebugScreenOverlayMixin.java
deleted file mode 100644
index c8201cfce..000000000
--- a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/DebugScreenOverlayMixin.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package dev.engine_room.flywheel.impl.mixin.fabric;
-
-import java.util.List;
-
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
-
-import dev.engine_room.flywheel.impl.FlwDebugInfo;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.gui.components.DebugScreenOverlay;
-
-@Mixin(DebugScreenOverlay.class)
-abstract class DebugScreenOverlayMixin {
- @Shadow
- @Final
- private Minecraft minecraft;
-
- @Inject(method = "getSystemInformation", at = @At("RETURN"))
- private void flywheel$onGetSystemInformation(CallbackInfoReturnable
> cir) {
- FlwDebugInfo.addDebugInfo(minecraft, cir.getReturnValue());
- }
-}
diff --git a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/MinecraftMixin.java b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/MinecraftMixin.java
index f87736ad1..9a4ecf2ad 100644
--- a/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/MinecraftMixin.java
+++ b/fabric/src/main/java/dev/engine_room/flywheel/impl/mixin/fabric/MinecraftMixin.java
@@ -15,17 +15,24 @@ abstract class MinecraftMixin {
@Shadow
public ClientLevel level;
- @Inject(method = "setLevel(Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/client/gui/screens/ReceivingLevelScreen$Reason;)V", at = @At("HEAD"))
+ @Inject(method = "setLevel(Lnet/minecraft/client/multiplayer/ClientLevel;)V", at = @At("HEAD"))
private void flywheel$onSetLevel(CallbackInfo ci) {
if (level != null) {
LevelAttached.invalidateLevel(level);
}
}
- @Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD"))
+ @Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;ZZ)V", at = @At("HEAD"))
private void flywheel$onDisconnect(CallbackInfo ci) {
if (level != null) {
LevelAttached.invalidateLevel(level);
}
}
+
+ @Inject(method = "clearClientLevel", at = @At("HEAD"))
+ private void flywheel$onClearClientLevel(CallbackInfo ci) {
+ if (level != null) {
+ LevelAttached.invalidateLevel(level);
+ }
+ }
}
diff --git a/fabric/src/main/resources/fabric.mod.json b/fabric/src/main/resources/fabric.mod.json
index 82729821e..765e3c343 100644
--- a/fabric/src/main/resources/fabric.mod.json
+++ b/fabric/src/main/resources/fabric.mod.json
@@ -1,12 +1,11 @@
{
"schemaVersion": 1,
- "id" : "${flywheel_id}",
- "version" : "${flywheel_version}",
- "name" : "${flywheel_name}",
- "description" : "${flywheel_description}",
+ "id": "${mod_id}",
+ "name": "${mod_name}",
+ "version": "${mod_version}",
+ "description": "${mod_description}",
"authors": [
- "Jozufozu",
- "PepperCode1"
+ "${mod_authors_json}"
],
"contact": {
"homepage": "${mod_homepage}",
@@ -27,11 +26,10 @@
"flywheel.impl.fabric.mixins.json"
],
"depends": {
- "minecraft": "${minecraft_semver_version_range}",
- "fabricloader": ">=0.15.0",
- "fabric-api": "${fabric_api_version_range}"
+ "minecraft": "${minecraft_version}",
+ "fabricloader": ">=${fabric_loader_version}",
+ "fabric-api": ">=${fabric_api_version}",
+ "java": ">=${java_version}"
},
- "breaks": {
- "sodium": "<0.6.0-beta.2"
- }
+ "accessWidener": "flywheel.accesswidener"
}
diff --git a/fabric/src/main/resources/flywheel.accesswidener b/fabric/src/main/resources/flywheel.accesswidener
new file mode 100644
index 000000000..4e3281a69
--- /dev/null
+++ b/fabric/src/main/resources/flywheel.accesswidener
@@ -0,0 +1,2 @@
+accessWidener v2 official
+accessible class com/mojang/blaze3d/opengl/GlDevice
diff --git a/fabric/src/main/resources/flywheel.impl.fabric.mixins.json b/fabric/src/main/resources/flywheel.impl.fabric.mixins.json
index de280fb0c..d3e0ee36a 100644
--- a/fabric/src/main/resources/flywheel.impl.fabric.mixins.json
+++ b/fabric/src/main/resources/flywheel.impl.fabric.mixins.json
@@ -2,11 +2,9 @@
"required": true,
"minVersion": "0.8",
"package": "dev.engine_room.flywheel.impl.mixin.fabric",
- "compatibilityLevel": "JAVA_21",
- "refmap": "flywheel.refmap.json",
+ "compatibilityLevel": "JAVA_25",
"client": [
"ArgumentTypeInfosAccessor",
- "DebugScreenOverlayMixin",
"MinecraftMixin",
"SystemReportMixin"
],
diff --git a/fabric/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java b/fabric/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java
deleted file mode 100644
index 6b05b1e62..000000000
--- a/fabric/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package dev.engine_room.flywheel;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.spongepowered.asm.mixin.MixinEnvironment;
-
-import net.fabricmc.api.ClientModInitializer;
-import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents;
-import net.fabricmc.loader.api.FabricLoader;
-
-public class FlywheelTestModClient implements ClientModInitializer {
- public static final String NAME = "Flywheel Test Mod";
- private static final Logger LOGGER = LoggerFactory.getLogger(NAME);
-
- @Override
- public void onInitializeClient() {
- LOGGER.info("Starting {} on EnvType: {}", NAME, FabricLoader.getInstance()
- .getEnvironmentType());
-
- ClientLifecycleEvents.CLIENT_STARTED.register(client -> {
- LOGGER.info("Running mixin audit");
- MixinEnvironment.getCurrentEnvironment()
- .audit();
-
- LOGGER.info("Stopping client");
- client.stop();
- });
- }
-}
diff --git a/fabric/src/testMod/resources/fabric.mod.json b/fabric/src/testMod/resources/fabric.mod.json
deleted file mode 100644
index f8c0b82c3..000000000
--- a/fabric/src/testMod/resources/fabric.mod.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "schemaVersion": 1,
- "id" : "${flywheel_id}_testmod",
- "name" : "${flywheel_name} Test Mod",
- "version": "1.0.0",
- "environment": "*",
- "license": "${mod_license}",
- "entrypoints": {
- "client": [
- "dev.engine_room.flywheel.FlywheelTestModClient"
- ]
- }
-}
diff --git a/gradle.properties b/gradle.properties
index 02295768e..faf95740a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -1,50 +1,32 @@
-org.gradle.jvmargs = -Xmx3G
+org.gradle.jvmargs = -Xmx2G
org.gradle.daemon = false
+org.gradle.parallel = true
+org.gradle.caching = true
+org.gradle.configuration-cache = true
+org.gradle.configuration-cache.parallel = true
+org.gradle.configureondemand = true
+org.gradle.warning.mode = all
+
# Common metadata
+base_group = dev.engine-room
mod_license = MIT
+mod_authors = Jozufozu, PepperCode1
mod_sources = https://github.com/Engine-Room/Flywheel
mod_issues = https://github.com/Engine-Room/Flywheel/issues
mod_homepage = https://github.com/Engine-Room/Flywheel
-# Flywheel metadata
-flywheel_id=flywheel
-flywheel_name=Flywheel
-flywheel_version=1.0.6
-flywheel_description=An overhauled entity and block entity rendering API.
-# Vanillin metadata
-vanillin_id=vanillin
-vanillin_name=Vanillin
-vanillin_version=1.1.3
-vanillin_description=Instanced rendering for entities and block entities via Flywheel.
-# Vanillin dependencies
-flywheel_maven_version_range=[1.0.0,2.0)
-flywheel_semver_version_range=>=1.0.0 <2.0.0
-
-# Mod dependency declarations
-minecraft_semver_version_range = >=1.21.1 <1.21.2
-minecraft_maven_version_range = [1.21.1,1.21.2)
-fabric_api_version_range = >=0.105.0
-neoforge_version_range = [21.1.66,)
-# General build dependency versions
-java_version = 21
-arch_loom_version = 1.7.412
-cursegradle_version = 1.4.0
-parchment_minecraft_version = 1.21
-parchment_version = 2024.07.07
-
-# Minecraft build dependency versions
-minecraft_version = 1.21.1
-neoforge_version = 21.1.66
-fabric_loader_version = 0.16.5
-fabric_api_version = 0.105.0+1.21.1
+# Flywheel metadata
+flywheel_id = flywheel
+flywheel_name = Flywheel
+flywheel_version = 1.0.6
+flywheel_description = An overhauled entity and block entity rendering API.
-# Build dependency mod versions
-sodium_version = mc1.21.1-0.6.5
-iris_version = 1.8.0-beta.8+1.21.1
-# There is no oculus for 1.21.1 so we will only support iris
-embeddium_version = 1.0.11+mc1.21.1
+# Vanillin metadata
+vanillin_id = vanillin
+vanillin_name = Vanillin
+vanillin_version = 1.1.3
+vanillin_description = Instanced rendering for entities and block entities via Flywheel.
-# Publication info
-flywheel_group=dev.engine-room.flywheel
-vanillin_group=dev.engine-room.vanillin
-artifact_minecraft_version = 1.21.1
+# Vanillin dependencies
+flywheel_maven_version_range = [1.0.0,2.0)
+flywheel_semver_version_range = >=1.0.0 <2.0.0
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 000000000..a632e03f3
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,61 @@
+[versions]
+java = "25"
+minecraft = "26.1.2"
+
+# https://neoforged.net
+mdg = "2.0.+"
+neoforge = "26.1.2.78"
+
+# https://fabricmc.net/develop
+loom = "1.17.+"
+fabric-loader = "0.19.3"
+fabric-api = "0.154.2+26.1.2"
+
+# we need to manually depend on mixin (+extras) in common
+mixin = "0.16.5+mixin.0.8.7"
+mixin-extras = "0.5.3"
+
+# https://maven.caffeinemc.net/#/releases/net/caffeinemc/sodium-fabric
+sodium = "0.9.1+mc26.1.2"
+# https://modrinth.com/mod/iris/versions
+iris-fabric = "1.11.2+26.1-fabric"
+iris-neoforge = "1.11.2+26.1-neoforge"
+
+junit = "6.1.1"
+
+[libraries]
+minecraft = { module = "com.mojang:minecraft", version.ref = "minecraft" }
+
+mdg = { module = "net.neoforged:moddev-gradle", version.ref = "mdg" }
+fabric-loom = { module = "net.fabricmc:fabric-loom", version.ref = "loom" }
+
+fabric-loader = { module = "net.fabricmc:fabric-loader", version.ref = "fabric-loader" }
+fabric-api = { module = "net.fabricmc.fabric-api:fabric-api", version.ref = "fabric-api" }
+
+mixin = { module = "net.fabricmc:sponge-mixin", version.ref = "mixin" }
+mixin-extras = { module = "io.github.llamalad7:mixinextras-common", version.ref = "mixin-extras" }
+
+sodium-fabric-api = { module = "net.caffeinemc:sodium-fabric-api", version.ref = "sodium" }
+sodium-neoforge-api = { module = "net.caffeinemc:sodium-neoforge-api", version.ref = "sodium" }
+
+iris-fabric = { module = "maven.modrinth:iris", version.ref = "iris-fabric" }
+iris-neoforge = { module = "maven.modrinth:iris", version.ref = "iris-neoforge" }
+
+junit-bom = { module = "org.junit:junit-bom", version.ref = "junit" }
+junit-jupiter = { module = "org.junit.jupiter:junit-jupiter" }
+junit-launcher = { module = "org.junit.platform:junit-platform-launcher" }
+
+[bundles]
+mixin = [ "mixin", "mixin-extras" ]
+
+[plugins]
+mdg = { id = "net.neoforged.moddev" }
+fabric-loom = { id = "net.fabricmc.fabric-loom" }
+
+flywheel-gradle = { id = "net.engine-room.flywheel-gradle"}
+
+configure-base = { id = "configure-base" }
+configure-common = { id = "configure-common" }
+configure-fabric = { id = "configure-fabric" }
+configure-neoforge = { id = "configure-neoforge" }
+setup-repositories = { id = "setup-repositories" }
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index a4b76b953..9bbc975c7 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index df97d72b8..a351597e6 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-9.6.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
diff --git a/gradlew b/gradlew
index f5feea6d6..faf93008b 100755
--- a/gradlew
+++ b/gradlew
@@ -86,8 +86,7 @@ done
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
-' "$PWD" ) || exit
+APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -206,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
diff --git a/javadoc-options.txt b/javadoc-options.txt
deleted file mode 100644
index 54fbbe259..000000000
--- a/javadoc-options.txt
+++ /dev/null
@@ -1,2 +0,0 @@
--Xdoclint:none
--quiet
diff --git a/neoforge/build.gradle.kts b/neoforge/build.gradle.kts
index 164c1c053..ce5fe4208 100644
--- a/neoforge/build.gradle.kts
+++ b/neoforge/build.gradle.kts
@@ -1,23 +1,19 @@
+import dev.engine_room.gradle.getExt
+
plugins {
- idea
- java
- `maven-publish`
- id("dev.architectury.loom")
- id("flywheel.subproject")
- id("flywheel.platform")
+ alias(libs.plugins.flywheel.gradle)
+ alias(libs.plugins.configure.base)
+ alias(libs.plugins.configure.neoforge)
+ alias(libs.plugins.setup.repositories)
}
-val common = ":common"
+val common = projects.flywheelCommon.path
val commonProject = project(common)
-subproject.init("flywheel-neoforge", "flywheel_group", "flywheel_version")
-
val api = sourceSets.create("api")
val lib = sourceSets.create("lib")
val backend = sourceSets.create("backend")
-val stubs = sourceSets.create("stubs")
val main = sourceSets.getByName("main")
-val testMod = sourceSets.create("testMod")
transitiveSourceSets {
compileClasspath = main.compileClasspath
@@ -41,11 +37,6 @@ transitiveSourceSets {
from(commonProject)
}
- sourceSet(stubs) {
- rootCompile()
-
- from(commonProject)
- }
sourceSet(main) {
compileClasspath(api, lib, backend)
@@ -53,57 +44,27 @@ transitiveSourceSets {
bundleOutput(api, lib, backend)
}
- sourceSet(testMod) {
- rootCompile()
- }
createCompileConfigurations()
}
-platform {
- setupLoomMod(api, lib, backend, main)
- setupLoomRuns()
- setupTestMod(testMod)
-}
+neoForge {
+ accessTransformers.from(file("src/main/resources/META-INF/accesstransformer.cfg"))
-val replaceProperties = listOf(
- "mod_license",
- "mod_sources",
- "mod_issues",
- "mod_homepage",
- "flywheel_id",
- "flywheel_name",
- "flywheel_description",
- "minecraft_maven_version_range",
- "neoforge_version_range",
-).associateWith { property(it) as String }
- .plus("flywheel_version" to "${property("flywheel_version")}${if (subproject.buildNumber != null) "-${subproject.buildNumber}" else ""}")
-
-tasks.withType().configureEach {
- inputs.properties(replaceProperties)
-
- filesMatching(listOf("pack.mcmeta", "META-INF/neoforge.mods.toml")) {
- expand(replaceProperties)
+ mods.getByName(getExt("mod_id")) {
+ sourceSet(api)
+ sourceSet(lib)
+ sourceSet(backend)
}
+
}
jarSets {
- mainSet.publishWithRawSources {
- artifactId = "flywheel-neoforge-${property("artifact_minecraft_version")}"
- }
mainSet.outgoing("flywheel")
create("api", api, lib).apply {
addToAssemble()
- publishWithRawSources {
- artifactId = "flywheel-neoforge-api-${property("artifact_minecraft_version")}"
- }
-
- configureJar {
- manifest {
- attributes("Fabric-Loom-Remap" to "true")
- }
- }
+ publish()
}
}
@@ -111,37 +72,13 @@ defaultPackageInfos {
sources(api, lib, backend, main)
}
-loom {
- mixin {
- useLegacyMixinAp = true
- add(main, "flywheel.refmap.json")
- add(backend, "backend-flywheel.refmap.json")
- }
-
- runs {
- configureEach {
- property("forge.logging.markers", "")
- property("forge.logging.console.level", "debug")
- }
- }
-}
-
-repositories {
- maven("https://maven.neoforged.net/releases/")
-}
-
dependencies {
- neoForge("net.neoforged:neoforge:${property("neoforge_version")}")
-
- modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-neoforge")
- modCompileOnly("maven.modrinth:iris:${property("iris_version")}-neoforge")
-
- modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}")
+ compileOnly(libs.sodium.neoforge.api)
+ compileOnly(libs.iris.neoforge)
"forApi"(project(path = common, configuration = "apiClasses"))
"forLib"(project(path = common, configuration = "libClasses"))
"forBackend"(project(path = common, configuration = "backendClasses"))
- "forStubs"(project(path = common, configuration = "stubsClasses"))
"forMain"(project(path = common, configuration = "mainClasses"))
"forLib"(project(path = common, configuration = "libResources"))
diff --git a/neoforge/gradle.properties b/neoforge/gradle.properties
deleted file mode 100644
index 2e6ed7676..000000000
--- a/neoforge/gradle.properties
+++ /dev/null
@@ -1 +0,0 @@
-loom.platform = neoforge
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java
deleted file mode 100644
index 131c17f1f..000000000
--- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BakedModelBufferer.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package dev.engine_room.flywheel.lib.model.baked;
-
-import java.util.Iterator;
-
-import org.jetbrains.annotations.Nullable;
-
-import com.mojang.blaze3d.vertex.BufferBuilder;
-import com.mojang.blaze3d.vertex.PoseStack;
-
-import dev.engine_room.flywheel.lib.model.SimpleModel;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.ItemBlockRenderTypes;
-import net.minecraft.client.renderer.RenderType;
-import net.minecraft.client.renderer.block.BlockRenderDispatcher;
-import net.minecraft.client.renderer.block.ModelBlockRenderer;
-import net.minecraft.client.renderer.texture.OverlayTexture;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.core.BlockPos;
-import net.minecraft.util.RandomSource;
-import net.minecraft.world.level.BlockAndTintGetter;
-import net.minecraft.world.level.block.RenderShape;
-import net.minecraft.world.level.block.state.BlockState;
-import net.minecraft.world.level.material.FluidState;
-import net.neoforged.neoforge.client.ChunkRenderTypeSet;
-import net.neoforged.neoforge.client.model.data.ModelData;
-import net.neoforged.neoforge.common.util.TriState;
-
-final class BakedModelBufferer {
- private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
-
- private BakedModelBufferer() {
- }
-
- public static SimpleModel bufferModel(BakedModel model, BlockPos pos, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, BlockMaterialFunction blockMaterialFunction) {
- ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
- if (poseStack == null) {
- poseStack = objects.identityPoseStack;
- }
- RandomSource random = objects.random;
- MeshEmitterManager emitters = objects.emitters;
-
- emitters.prepare(blockMaterialFunction);
-
- ModelBlockRenderer blockRenderer = Minecraft.getInstance()
- .getBlockRenderer()
- .getModelRenderer();
-
- long seed = state.getSeed(pos);
- ModelData modelData = model.getModelData(level, pos, state, level.getModelData(pos));
- random.setSeed(seed);
- ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData);
-
- // See ModelBlockRenderer#tesselateBlock
- boolean defaultAo = state.getLightEmission(level, pos) == 0;
- boolean aoEnabled = Minecraft.useAmbientOcclusion();
-
- for (RenderType renderType : renderTypes) {
- TriState useAo = model.useAmbientOcclusion(state, modelData, renderType);
-
- boolean defaultAoLayer = aoEnabled && (useAo.isTrue() || (useAo.isDefault() && defaultAo));
-
- NeoforgeMeshEmitter emitter = emitters.getEmitter(renderType);
- emitter.prepareForModelLayer(defaultAoLayer);
-
- poseStack.pushPose();
- blockRenderer.tesselateBlock(level, model, state, pos, poseStack, emitter, false, random, seed, OverlayTexture.NO_OVERLAY, modelData, renderType);
- poseStack.popPose();
- }
-
- return emitters.end();
- }
-
- public static SimpleModel bufferBlocks(Iterator posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, BlockMaterialFunction blockMaterialFunction) {
- ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
- if (poseStack == null) {
- poseStack = objects.identityPoseStack;
- }
- RandomSource random = objects.random;
- MeshEmitterManager emitters = objects.emitters;
- TransformingVertexConsumer transformingWrapper = objects.transformingWrapper;
-
- emitters.prepare(blockMaterialFunction);
-
- BlockRenderDispatcher renderDispatcher = Minecraft.getInstance()
- .getBlockRenderer();
- ModelBlockRenderer blockRenderer = renderDispatcher.getModelRenderer();
- ModelBlockRenderer.enableCaching();
-
- boolean aoEnabled = Minecraft.useAmbientOcclusion();
-
- while (posIterator.hasNext()) {
- BlockPos pos = posIterator.next();
- BlockState state = level.getBlockState(pos);
-
- emitters.prepareForBlock();
-
- if (renderFluids) {
- FluidState fluidState = state.getFluidState();
-
- if (!fluidState.isEmpty()) {
- RenderType renderType = ItemBlockRenderTypes.getRenderLayer(fluidState);
-
- BufferBuilder bufferBuilder = emitters.getBuffer(renderType, true, false);
-
- if (bufferBuilder != null) {
- transformingWrapper.prepare(bufferBuilder, poseStack);
-
- poseStack.pushPose();
- poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF));
- renderDispatcher.renderLiquid(pos, level, transformingWrapper, state, fluidState);
- poseStack.popPose();
- }
- }
- }
-
- if (state.getRenderShape() == RenderShape.MODEL) {
- long seed = state.getSeed(pos);
- BakedModel model = renderDispatcher.getBlockModel(state);
- ModelData modelData = model.getModelData(level, pos, state, level.getModelData(pos));
- random.setSeed(seed);
- ChunkRenderTypeSet renderTypes = model.getRenderTypes(state, random, modelData);
-
- // See ModelBlockRenderer#tesselateBlock
- boolean defaultAo = state.getLightEmission(level, pos) == 0;
-
- for (RenderType renderType : renderTypes) {
- TriState useAo = model.useAmbientOcclusion(state, modelData, renderType);
-
- boolean defaultAoLayer = aoEnabled && (useAo.isTrue() || (useAo.isDefault() && defaultAo));
-
- NeoforgeMeshEmitter emitter = emitters.getEmitter(renderType);
- emitter.prepareForModelLayer(defaultAoLayer);
-
- poseStack.pushPose();
- poseStack.translate(pos.getX(), pos.getY(), pos.getZ());
- blockRenderer.tesselateBlock(level, model, state, pos, poseStack, emitter, true, random, seed, OverlayTexture.NO_OVERLAY, modelData, renderType);
- poseStack.popPose();
- }
- }
- }
-
- ModelBlockRenderer.clearCache();
- transformingWrapper.clear();
- return emitters.end();
- }
-
- private static class ThreadLocalObjects {
- public final PoseStack identityPoseStack = new PoseStack();
- public final RandomSource random = RandomSource.createNewThreadLocalInstance();
-
- public final MeshEmitterManager emitters = new MeshEmitterManager<>(NeoforgeMeshEmitter::new);
- public final TransformingVertexConsumer transformingWrapper = new TransformingVertexConsumer();
- }
-}
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java
new file mode 100644
index 000000000..bbce84765
--- /dev/null
+++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/BlockStateModelBufferer.java
@@ -0,0 +1,178 @@
+package dev.engine_room.flywheel.lib.model.baked;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jetbrains.annotations.ApiStatus.Internal;
+import org.jspecify.annotations.Nullable;
+
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.PoseStack;
+
+import dev.engine_room.flywheel.lib.model.SimpleModel;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.color.block.BlockColors;
+import net.minecraft.client.renderer.block.BlockAndTintGetter;
+import net.minecraft.client.renderer.block.BlockModelLighter;
+import net.minecraft.client.renderer.block.FluidRenderer;
+import net.minecraft.client.renderer.block.ModelBlockRenderer;
+import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
+import net.minecraft.client.renderer.block.dispatch.BlockStateModelPart;
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
+import net.minecraft.client.renderer.state.GameRenderState;
+import net.minecraft.client.resources.model.ModelManager;
+import net.minecraft.core.BlockPos;
+import net.minecraft.util.RandomSource;
+import net.minecraft.world.level.block.RenderShape;
+import net.minecraft.world.level.block.state.BlockState;
+import net.minecraft.world.level.material.FluidState;
+import net.neoforged.neoforge.client.config.NeoForgeClientConfig;
+
+@Internal
+public final class BlockStateModelBufferer {
+ private static final ThreadLocal THREAD_LOCAL_OBJECTS = ThreadLocal.withInitial(ThreadLocalObjects::new);
+
+ public static final ScopedValue EMITTER_MANAGER = ScopedValue.newInstance();
+
+ private BlockStateModelBufferer() {
+ }
+
+ public static SimpleModel bufferModel(BlockStateModel model, BlockPos pos, BlockAndTintGetter level, BlockState state, @Nullable PoseStack poseStack, BlockMaterialFunction blockMaterialFunction) {
+ ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
+ if (poseStack == null) {
+ poseStack = objects.identityPoseStack;
+ }
+ List parts = objects.parts;
+ RandomSource random = objects.random;
+ NeoForgeMeshEmitterManager emitters = objects.emitters;
+
+ emitters.prepare(blockMaterialFunction);
+
+ long seed = state.getSeed(pos);
+ random.setSeed(seed);
+ model.collectParts(level, pos, state, random, parts);
+
+ Minecraft minecraft = Minecraft.getInstance();
+ GameRenderState gameRenderState = minecraft.gameRenderer.getGameRenderState();
+ BlockColors blockColors = minecraft.getBlockColors();
+
+ // See ModelBlockRenderer#tesselateBlock
+ boolean useAo = gameRenderState.optionsRenderState.ambientOcclusion;
+ boolean perPartAo = NeoForgeClientConfig.INSTANCE.handleAmbientOcclusionPerPart.getAsBoolean();
+ boolean ao = useAo && (perPartAo || parts.isEmpty() || switch(parts.getFirst().ambientOcclusion()) {
+ case TRUE -> true;
+ case DEFAULT -> state.getLightEmission(level, pos) == 0;
+ case FALSE -> false;
+ });
+ emitters.prepareForModel(ao);
+
+ ModelBlockRenderer blockRenderer = new ModelBlockRenderer(useAo, true, blockColors);
+
+ PoseStack finalPoseStack = poseStack;
+ ScopedValue.where(EMITTER_MANAGER, emitters).run(() ->
+ blockRenderer.tesselateBlock((_, _, _, quad, instance) -> {
+ finalPoseStack.pushPose();
+ ChunkSectionLayer layer = quad.materialInfo().layer();
+ emitters.getEmitter(layer).putBakedQuad(finalPoseStack.last(), quad, instance);
+ finalPoseStack.popPose();
+ }, 0, 0, 0, level, pos, state, model, seed)
+ );
+
+ return emitters.end();
+ }
+
+ public static SimpleModel bufferBlocks(Iterator posIterator, BlockAndTintGetter level, @Nullable PoseStack poseStack, boolean renderFluids, BlockMaterialFunction blockMaterialFunction) {
+ ThreadLocalObjects objects = THREAD_LOCAL_OBJECTS.get();
+ if (poseStack == null) {
+ poseStack = objects.identityPoseStack;
+ }
+ List parts = objects.parts;
+ RandomSource random = objects.random;
+ NeoForgeMeshEmitterManager emitters = objects.emitters;
+ TransformingVertexConsumer transformingWrapper = objects.transformingWrapper;
+
+ emitters.prepare(blockMaterialFunction);
+
+ BlockModelLighter.enableCaching();
+
+ Minecraft minecraft = Minecraft.getInstance();
+ ModelManager modelManager = minecraft.getModelManager();
+ GameRenderState gameRenderState = minecraft.gameRenderer.getGameRenderState();
+ boolean useAo = gameRenderState.optionsRenderState.ambientOcclusion;
+ BlockColors blockColors = minecraft.getBlockColors();
+
+ ModelBlockRenderer blockRenderer = new ModelBlockRenderer(useAo, true, blockColors);
+ FluidRenderer fluidRenderer = new FluidRenderer(modelManager.getFluidStateModelSet());
+
+ boolean perPartAo = NeoForgeClientConfig.INSTANCE.handleAmbientOcclusionPerPart.getAsBoolean();
+
+ while (posIterator.hasNext()) {
+ BlockPos pos = posIterator.next();
+ BlockState state = level.getBlockState(pos);
+
+ emitters.prepareForBlock();
+
+ if (renderFluids) {
+ FluidState fluidState = state.getFluidState();
+
+ if (!fluidState.isEmpty()) {
+ poseStack.pushPose();
+ poseStack.translate(pos.getX() - (pos.getX() & 0xF), pos.getY() - (pos.getY() & 0xF), pos.getZ() - (pos.getZ() & 0xF));
+ PoseStack finalPoseStack = poseStack;
+ fluidRenderer.tesselate(level, pos, layer -> {
+ BufferBuilder bufferBuilder = emitters.getEmitter(layer).getBuffer(true, false);
+
+ if (bufferBuilder != null) {
+ transformingWrapper.prepare(bufferBuilder, finalPoseStack);
+ return transformingWrapper;
+ }
+
+ return EmptyVertexConsumer.INSTANCE;
+ }, state, fluidState);
+ poseStack.popPose();
+ }
+ }
+
+ if (state.getRenderShape() == RenderShape.MODEL) {
+ long seed = state.getSeed(pos);
+ random.setSeed(seed);
+
+ BlockStateModel model = modelManager.getBlockStateModelSet().get(state);
+ model.collectParts(level, pos, state, random, parts);
+
+ // See ModelBlockRenderer#tesselateBlock
+ boolean ao = useAo && (perPartAo || parts.isEmpty() || switch(parts.getFirst().ambientOcclusion()) {
+ case TRUE -> true;
+ case DEFAULT -> state.getLightEmission(level, pos) == 0;
+ case FALSE -> false;
+ });
+ emitters.prepareForModel(ao);
+
+ PoseStack finalPoseStack = poseStack;
+ ScopedValue.where(EMITTER_MANAGER, emitters).run(() ->
+ blockRenderer.tesselateBlock((x, y, z, quad, instance) -> {
+ finalPoseStack.pushPose();
+ finalPoseStack.translate(x, y, z);
+ ChunkSectionLayer layer = quad.materialInfo().layer();
+ emitters.getEmitter(layer).putBakedQuad(finalPoseStack.last(), quad, instance);
+ finalPoseStack.popPose();
+ }, pos.getX(), pos.getY(), pos.getZ(), level, pos, state, model, seed)
+ );
+ }
+ }
+
+ BlockModelLighter.clearCache();
+ transformingWrapper.clear();
+ return emitters.end();
+ }
+
+ private static class ThreadLocalObjects {
+ public final PoseStack identityPoseStack = new PoseStack();
+ public final List parts = new ArrayList<>();
+ public final RandomSource random = RandomSource.createThreadLocalInstance();
+
+ public final NeoForgeMeshEmitterManager emitters = new NeoForgeMeshEmitterManager();
+ public final TransformingVertexConsumer transformingWrapper = new TransformingVertexConsumer();
+ }
+}
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java
index 4a0bcc4dd..741aa54c3 100644
--- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java
+++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/ModelBuilderImpl.java
@@ -11,13 +11,13 @@ public final class ModelBuilderImpl {
private ModelBuilderImpl() {
}
- public static SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) {
+ public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
BlockState blockState = builder.level.getBlockState(builder.pos);
- return BakedModelBufferer.bufferModel(builder.bakedModel, builder.pos, builder.level, blockState, builder.poseStack, builder.materialFunc);
+ return BlockStateModelBufferer.bufferModel(builder.blockModel, builder.pos, builder.level, blockState, builder.poseStack, builder.materialFunc);
}
- public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
- return BakedModelBufferer.bufferBlocks(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, builder.materialFunc);
+ public static SimpleModel buildLevelModelBuilder(LevelModelBuilder builder) {
+ return BlockStateModelBufferer.bufferBlocks(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, builder.materialFunc);
}
}
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitter.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitter.java
new file mode 100644
index 000000000..b9683edd5
--- /dev/null
+++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitter.java
@@ -0,0 +1,95 @@
+package dev.engine_room.flywheel.lib.model.baked;
+
+import org.jetbrains.annotations.ApiStatus;
+import org.jspecify.annotations.Nullable;
+
+import com.mojang.blaze3d.vertex.BufferBuilder;
+import com.mojang.blaze3d.vertex.PoseStack.Pose;
+import com.mojang.blaze3d.vertex.QuadInstance;
+import com.mojang.blaze3d.vertex.VertexConsumer;
+
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
+import net.minecraft.client.resources.model.geometry.BakedQuad;
+import net.neoforged.neoforge.client.model.quad.MutableQuad;
+
+@ApiStatus.Internal
+public class NeoForgeMeshEmitter extends MeshEmitter {
+ private boolean ao;
+
+ NeoForgeMeshEmitter(ByteBufferBuilderStack byteBufferBuilderStack, ChunkSectionLayer chunkSectionLayer) {
+ super(byteBufferBuilderStack, chunkSectionLayer);
+ }
+
+ // Called from ModelBlockRendererMixin if AO is on for the model before each part is buffered
+ public void prepareForPart(boolean ao) {
+ this.ao = ao;
+ }
+
+ @Nullable
+ private BufferBuilder getBuffer(BakedQuad quad) {
+ boolean shade = quad.materialInfo().shade();
+ boolean ao = quad.materialInfo().ambientOcclusion() && this.ao;
+ return getBuffer(shade, ao);
+ }
+
+ @Override
+ public void putBakedQuad(Pose pose, BakedQuad quad, QuadInstance instance) {
+ BufferBuilder bufferBuilder = getBuffer(quad);
+ if (bufferBuilder != null) {
+ bufferBuilder.putBakedQuad(pose, quad, instance);
+ }
+ }
+
+ @Override
+ public void putBlockBakedQuad(float x, float y, float z, BakedQuad quad, QuadInstance instance) {
+ BufferBuilder bufferBuilder = getBuffer(quad);
+ if (bufferBuilder != null) {
+ bufferBuilder.putBlockBakedQuad(x, y, z, quad, instance);
+ }
+ }
+
+ @Override
+ public void putMutableQuad(Pose pose, MutableQuad quad, QuadInstance instance) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+
+ @Override
+ public VertexConsumer addVertex(float x, float y, float z) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+
+ @Override
+ public VertexConsumer setColor(int red, int green, int blue, int alpha) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+
+ @Override
+ public VertexConsumer setColor(int color) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+
+ @Override
+ public VertexConsumer setUv(float u, float v) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+
+ @Override
+ public VertexConsumer setUv1(int u, int v) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+
+ @Override
+ public VertexConsumer setUv2(int u, int v) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+
+ @Override
+ public VertexConsumer setNormal(float normalX, float normalY, float normalZ) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+
+ @Override
+ public VertexConsumer setLineWidth(float width) {
+ throw new UnsupportedOperationException("NeoForgeMeshEmitter only supports putBakedQuad/putBlockBakedQuad!");
+ }
+}
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitterManager.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitterManager.java
new file mode 100644
index 000000000..3b9f07001
--- /dev/null
+++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeMeshEmitterManager.java
@@ -0,0 +1,27 @@
+package dev.engine_room.flywheel.lib.model.baked;
+
+import java.util.function.Function;
+
+import org.jetbrains.annotations.ApiStatus.Internal;
+
+import com.mojang.blaze3d.vertex.VertexConsumer;
+
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
+
+@Internal
+public class NeoForgeMeshEmitterManager extends MeshEmitterManager implements Function {
+ NeoForgeMeshEmitterManager() {
+ super(NeoForgeMeshEmitter::new);
+ }
+
+ public void prepareForModel(boolean ao) {
+ for (NeoForgeMeshEmitter meshEmitter : emitterMap.values()) {
+ meshEmitter.prepareForPart(ao);
+ }
+ }
+
+ @Override
+ public VertexConsumer apply(ChunkSectionLayer chunkSectionLayer) {
+ return getEmitter(chunkSectionLayer);
+ }
+}
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgePartialModel.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgePartialModel.java
new file mode 100644
index 000000000..609b3a238
--- /dev/null
+++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgePartialModel.java
@@ -0,0 +1,65 @@
+package dev.engine_room.flywheel.lib.model.baked;
+
+import java.util.concurrent.ConcurrentMap;
+
+import org.jetbrains.annotations.ApiStatus;
+
+import com.google.common.collect.MapMaker;
+
+import net.minecraft.client.renderer.block.dispatch.BlockModelRotation;
+import net.minecraft.client.renderer.block.dispatch.BlockStateModel;
+import net.minecraft.client.renderer.block.dispatch.SingleVariant;
+import net.minecraft.client.resources.model.ModelBaker;
+import net.minecraft.client.resources.model.ModelDebugName;
+import net.minecraft.client.resources.model.ModelManager;
+import net.minecraft.client.resources.model.ResolvableModel;
+import net.minecraft.client.resources.model.SimpleModelWrapper;
+import net.minecraft.resources.Identifier;
+import net.neoforged.neoforge.client.event.ModelEvent;
+import net.neoforged.neoforge.client.model.standalone.StandaloneModelKey;
+import net.neoforged.neoforge.client.model.standalone.UnbakedStandaloneModel;
+
+import org.jspecify.annotations.NullMarked;
+
+@ApiStatus.Internal
+public class NeoForgePartialModel extends PartialModel {
+ private static final ConcurrentMap ALL = new MapMaker().weakValues().makeMap();
+
+ private final StandaloneModelKey key;
+
+ public NeoForgePartialModel(Identifier modelId) {
+ super(modelId);
+ key = new StandaloneModelKey<>(modelId::toString);
+ }
+
+ public static NeoForgePartialModel of(Identifier modelId) {
+ return ALL.computeIfAbsent(modelId, NeoForgePartialModel::new);
+ }
+
+ public static void registerAll(ModelEvent.RegisterStandalone event) {
+ for (NeoForgePartialModel partial : ALL.values()) {
+ event.register(partial.key, partial.new Unbaked());
+ }
+ }
+
+ public static void refreshAll(ModelEvent.BakingCompleted event) {
+ ModelManager modelManager = event.getModelManager();
+
+ for (NeoForgePartialModel partial : ALL.values()) {
+ partial.blockStateModel = modelManager.getStandaloneModel(partial.key);
+ }
+ }
+
+ @NullMarked
+ private class Unbaked implements UnbakedStandaloneModel {
+ @Override
+ public BlockStateModel bake(ModelBaker baker, ModelDebugName name) {
+ return new SingleVariant(SimpleModelWrapper.bake(baker, modelId, BlockModelRotation.IDENTITY));
+ }
+
+ @Override
+ public void resolveDependencies(ResolvableModel.Resolver resolver) {
+ resolver.markDependency(modelId);
+ }
+ }
+}
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeSinglePosVirtualBlockGetter.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeSinglePosVirtualBlockGetter.java
index 41291b65e..5eb2d475e 100644
--- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeSinglePosVirtualBlockGetter.java
+++ b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoForgeSinglePosVirtualBlockGetter.java
@@ -2,12 +2,12 @@
import java.util.function.ToIntFunction;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
-import net.neoforged.neoforge.client.model.data.ModelData;
+import net.neoforged.neoforge.model.data.ModelData;
public class NeoForgeSinglePosVirtualBlockGetter extends SinglePosVirtualBlockGetter {
@Nullable
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoforgeMeshEmitter.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoforgeMeshEmitter.java
deleted file mode 100644
index ded11be75..000000000
--- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/NeoforgeMeshEmitter.java
+++ /dev/null
@@ -1,99 +0,0 @@
-package dev.engine_room.flywheel.lib.model.baked;
-
-import org.jetbrains.annotations.ApiStatus;
-import org.jetbrains.annotations.Nullable;
-
-import com.mojang.blaze3d.vertex.BufferBuilder;
-import com.mojang.blaze3d.vertex.PoseStack;
-import com.mojang.blaze3d.vertex.VertexConsumer;
-
-import dev.engine_room.flywheel.api.material.Material;
-import net.minecraft.client.renderer.RenderType;
-import net.minecraft.client.renderer.block.ModelBlockRenderer;
-import net.minecraft.client.renderer.block.model.BakedQuad;
-
-@ApiStatus.Internal
-public class NeoforgeMeshEmitter extends MeshEmitter implements VertexConsumer {
- private final RenderType renderType;
-
- private boolean defaultAo;
-
- NeoforgeMeshEmitter(ByteBufferBuilderStack byteBufferBuilderStack, RenderType renderType) {
- super(byteBufferBuilderStack, renderType);
- this.renderType = renderType;
- }
-
- /**
- * Some mods, like FramedBlocks, have custom hooks to determine the default AO. This method is invoked a second time
- * from within a mixin to {@link ModelBlockRenderer} after the accurate value is computed, so we don't need to
- * support those custom hooks manually. It is possible that the mixin injector will never run (primarily due to
- * implementations of Fabric Renderer API on Forge, like Indigo in Forgified Fabric API), so we always compute the
- * value manually beforehand too.
- */
- public void prepareForModelLayer(boolean defaultAo) {
- this.defaultAo = defaultAo;
- }
-
- @Nullable
- private BufferBuilder getBuffer(boolean shade, boolean ao) {
- Material key = blockMaterialFunction.apply(renderType, shade, ao);
- if (key != null) {
- return getBuffer(key);
- } else {
- return null;
- }
- }
-
- @Nullable
- private BufferBuilder getBuffer(BakedQuad quad) {
- boolean shade = quad.isShade();
- boolean ao = quad.hasAmbientOcclusion() && defaultAo;
- return getBuffer(shade, ao);
- }
-
- @Override
- public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, float alpha, int packedLight, int packedOverlay) {
- BufferBuilder bufferBuilder = getBuffer(quad);
- if (bufferBuilder != null) {
- bufferBuilder.putBulkData(pose, quad, red, green, blue, alpha, packedLight, packedOverlay);
- }
- }
-
- @Override
- public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightness, float red, float green, float blue, float alpha, int[] lightmap, int packedOverlay, boolean readAlpha) {
- BufferBuilder bufferBuilder = getBuffer(quad);
- if (bufferBuilder != null) {
- bufferBuilder.putBulkData(pose, quad, brightness, red, green, blue, alpha, lightmap, packedOverlay, readAlpha);
- }
- }
-
- @Override
- public VertexConsumer addVertex(float x, float y, float z) {
- throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!");
- }
-
- @Override
- public VertexConsumer setColor(int red, int green, int blue, int alpha) {
- throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!");
- }
-
- @Override
- public VertexConsumer setUv(float u, float v) {
- throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!");
- }
-
- @Override
- public VertexConsumer setUv1(int u, int v) {
- throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!");
- }
-
- @Override
- public VertexConsumer setUv2(int u, int v) {
- throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!");
- }
-
- @Override
- public VertexConsumer setNormal(float normalX, float normalY, float normalZ) {
- throw new UnsupportedOperationException("ForgeMeshEmitter only supports putBulkData!");
- }
-}
diff --git a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java b/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java
deleted file mode 100644
index d87eee208..000000000
--- a/neoforge/src/lib/java/dev/engine_room/flywheel/lib/model/baked/PartialModelEventHandler.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package dev.engine_room.flywheel.lib.model.baked;
-
-import java.util.Map;
-
-import org.jetbrains.annotations.ApiStatus;
-
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.client.resources.model.ModelResourceLocation;
-import net.minecraft.resources.ResourceLocation;
-import net.neoforged.neoforge.client.event.ModelEvent;
-
-@ApiStatus.Internal
-public final class PartialModelEventHandler {
- private PartialModelEventHandler() {
- }
-
- public static void onRegisterAdditional(ModelEvent.RegisterAdditional event) {
- for (ResourceLocation modelLocation : PartialModel.ALL.keySet()) {
- event.register(ModelResourceLocation.standalone(modelLocation));
- }
- }
-
- public static void onBakingCompleted(ModelEvent.BakingCompleted event) {
- PartialModel.populateOnInit = true;
- Map models = event.getModels();
-
- for (PartialModel partial : PartialModel.ALL.values()) {
- partial.bakedModel = models.get(ModelResourceLocation.standalone(partial.modelLocation()));
- }
- }
-}
diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java
index f754fc992..e4fbda838 100644
--- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java
+++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwImplXplatImpl.java
@@ -2,13 +2,13 @@
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
import net.minecraft.client.multiplayer.ClientLevel;
-import net.neoforged.fml.loading.LoadingModList;
+import net.neoforged.fml.loading.FMLLoader;
import net.neoforged.neoforge.common.NeoForge;
public class FlwImplXplatImpl implements FlwImplXplat {
@Override
public boolean isModLoaded(String modId) {
- return LoadingModList.get().getModFileById(modId) != null;
+ return FMLLoader.getCurrent().getLoadingModList().getModFileById(modId) != null;
}
@Override
diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java
index c5ccd80f6..45d1ab393 100644
--- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java
+++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlwLibXplatImpl.java
@@ -1,31 +1,27 @@
package dev.engine_room.flywheel.impl;
-import org.jetbrains.annotations.UnknownNullability;
-
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
import dev.engine_room.flywheel.lib.model.SimpleModel;
-import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
+import dev.engine_room.flywheel.lib.model.baked.LevelModelBuilder;
import dev.engine_room.flywheel.lib.model.baked.ModelBuilderImpl;
-import net.minecraft.client.resources.model.BakedModel;
-import net.minecraft.client.resources.model.ModelManager;
-import net.minecraft.client.resources.model.ModelResourceLocation;
-import net.minecraft.resources.ResourceLocation;
+import dev.engine_room.flywheel.lib.model.baked.NeoForgePartialModel;
+import dev.engine_room.flywheel.lib.model.baked.PartialModel;
+import net.minecraft.resources.Identifier;
public class FlwLibXplatImpl implements FlwLibXplat {
@Override
- @UnknownNullability
- public BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location) {
- return modelManager.getModel(ModelResourceLocation.standalone(location));
+ public PartialModel createPartialModel(Identifier modelId) {
+ return NeoForgePartialModel.of(modelId);
}
@Override
- public SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) {
- return ModelBuilderImpl.buildBakedModelBuilder(builder);
+ public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
+ return ModelBuilderImpl.buildBlockModelBuilder(builder);
}
@Override
- public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
- return ModelBuilderImpl.buildBlockModelBuilder(builder);
+ public SimpleModel buildLevelModelBuilder(LevelModelBuilder builder) {
+ return ModelBuilderImpl.buildLevelModelBuilder(builder);
}
}
diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlywheelNeoForge.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlywheelNeoForge.java
index ea451b17e..71b714ef9 100644
--- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlywheelNeoForge.java
+++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/FlywheelNeoForge.java
@@ -8,9 +8,10 @@
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
import dev.engine_room.flywheel.backend.compile.FlwProgramsReloader;
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
-import dev.engine_room.flywheel.impl.compat.EmbeddiumCompat;
+import dev.engine_room.flywheel.impl.task.FlwTaskExecutor;
import dev.engine_room.flywheel.impl.visualization.VisualizationEventHandler;
-import dev.engine_room.flywheel.lib.model.baked.PartialModelEventHandler;
+import dev.engine_room.flywheel.lib.model.baked.NeoForgePartialModel;
+import dev.engine_room.flywheel.lib.util.IdentifierUtil;
import dev.engine_room.flywheel.lib.util.LevelAttached;
import dev.engine_room.flywheel.lib.util.RendererReloadCache;
import dev.engine_room.flywheel.lib.util.ResourceReloadHolder;
@@ -22,8 +23,9 @@
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.common.Mod;
import net.neoforged.fml.event.lifecycle.FMLCommonSetupEvent;
-import net.neoforged.neoforge.client.event.CustomizeGuiOverlayEvent;
-import net.neoforged.neoforge.client.event.RegisterClientReloadListenersEvent;
+import net.neoforged.neoforge.client.event.AddClientReloadListenersEvent;
+import net.neoforged.neoforge.client.event.RegisterDebugEntriesEvent;
+import net.neoforged.neoforge.client.event.lifecycle.ClientStoppingEvent;
import net.neoforged.neoforge.common.NeoForge;
import net.neoforged.neoforge.event.entity.EntityJoinLevelEvent;
import net.neoforged.neoforge.event.entity.EntityLeaveLevelEvent;
@@ -50,11 +52,11 @@ public FlywheelNeoForge(IEventBus modEventBus, ModContainer modContainer) {
CrashReportCallables.registerCrashCallable("Flywheel Backend", BackendManagerImpl::getBackendString);
FlwImpl.init();
-
- EmbeddiumCompat.init();
}
private static void registerImplEventListeners(IEventBus gameEventBus, IEventBus modEventBus) {
+ gameEventBus.addListener((ClientStoppingEvent e) -> FlwTaskExecutor.get().shutdown());
+
gameEventBus.addListener((ReloadLevelRendererEvent e) -> BackendManagerImpl.onReloadLevelRenderer(e.level()));
gameEventBus.addListener((LevelTickEvent.Post e) -> {
@@ -68,15 +70,7 @@ private static void registerImplEventListeners(IEventBus gameEventBus, IEventBus
gameEventBus.addListener(FlwCommands::registerClientCommands);
- gameEventBus.addListener((CustomizeGuiOverlayEvent.DebugText e) -> {
- Minecraft minecraft = Minecraft.getInstance();
-
- if (!minecraft.getDebugOverlay().showDebugScreen()) {
- return;
- }
-
- FlwDebugInfo.addDebugInfo(minecraft, e.getRight());
- });
+ modEventBus.addListener((RegisterDebugEntriesEvent e) -> e.register(FlwDebugInfo.FlwDebugEntry.ID, new FlwDebugInfo.FlwDebugEntry()));
modEventBus.addListener((EndClientResourceReloadEvent e) -> BackendManagerImpl.onEndClientResourceReload(e.error().isPresent()));
@@ -95,15 +89,15 @@ private static void registerLibEventListeners(IEventBus gameEventBus, IEventBus
modEventBus.addListener((EndClientResourceReloadEvent e) -> RendererReloadCache.onReloadLevelRenderer());
modEventBus.addListener((EndClientResourceReloadEvent e) -> ResourceReloadHolder.onEndClientResourceReload());
- modEventBus.addListener(PartialModelEventHandler::onRegisterAdditional);
- modEventBus.addListener(PartialModelEventHandler::onBakingCompleted);
+ modEventBus.addListener(NeoForgePartialModel::registerAll);
+ modEventBus.addListener(NeoForgePartialModel::refreshAll);
}
private static void registerBackendEventListeners(IEventBus gameEventBus, IEventBus modEventBus) {
gameEventBus.addListener((ReloadLevelRendererEvent e) -> Uniforms.onReloadLevelRenderer());
- modEventBus.addListener((RegisterClientReloadListenersEvent e) -> {
- e.registerReloadListener(FlwProgramsReloader.INSTANCE);
+ modEventBus.addListener((AddClientReloadListenersEvent e) -> {
+ e.addListener(FlwProgramsReloader.ID, FlwProgramsReloader.INSTANCE);
});
}
diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java
index d1445bc19..09d6e0b47 100644
--- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java
+++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java
@@ -1,14 +1,14 @@
package dev.engine_room.flywheel.impl;
import org.apache.commons.lang3.tuple.Pair;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.backend.Backend;
import dev.engine_room.flywheel.api.backend.BackendManager;
import dev.engine_room.flywheel.backend.BackendConfig;
import dev.engine_room.flywheel.backend.compile.LightSmoothness;
-import net.minecraft.ResourceLocationException;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.IdentifierException;
+import net.minecraft.resources.Identifier;
import net.neoforged.fml.ModContainer;
import net.neoforged.fml.config.ModConfig;
import net.neoforged.neoforge.common.ModConfigSpec;
@@ -42,11 +42,11 @@ private static Backend parseBackend(String value) {
return BackendManager.defaultBackend();
}
- ResourceLocation backendId;
+ Identifier backendId;
try {
- backendId = ResourceLocation.parse(value);
- } catch (ResourceLocationException e) {
- FlwImpl.CONFIG_LOGGER.warn("'backend' value '{}' is not a valid resource location", value);
+ backendId = Identifier.parse(value);
+ } catch (IdentifierException e) {
+ FlwImpl.CONFIG_LOGGER.warn("'backend' value '{}' is not a valid resource id", value);
return null;
}
diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/compat/EmbeddiumCompat.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/compat/EmbeddiumCompat.java
deleted file mode 100644
index cd1e5e138..000000000
--- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/compat/EmbeddiumCompat.java
+++ /dev/null
@@ -1,33 +0,0 @@
-package dev.engine_room.flywheel.impl.compat;
-
-import org.embeddedt.embeddium.api.ChunkDataBuiltEvent;
-
-import dev.engine_room.flywheel.impl.FlwImpl;
-import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
-
-public final class EmbeddiumCompat {
- public static final boolean ACTIVE = CompatMod.EMBEDDIUM.isLoaded;
-
- static {
- if (ACTIVE) {
- FlwImpl.LOGGER.debug("Detected Embeddium");
- }
- }
-
- private EmbeddiumCompat() {
- }
-
- public static void init() {
- if (ACTIVE) {
- Internals.init();
- }
- }
-
- private static final class Internals {
- static void init() {
- ChunkDataBuiltEvent.BUS.addListener(event -> {
- event.getDataBuilder().removeBlockEntitiesIf(VisualizationHelper::tryAddBlockEntity);
- });
- }
- }
-}
diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java
index 50950fbab..2c6f42597 100644
--- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java
+++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/MinecraftMixin.java
@@ -28,12 +28,12 @@ abstract class MinecraftMixin {
FlwImpl.freezeRegistries();
}
- @Inject(method = "lambda$new$8", at = @At("HEAD"), remap = false)
+ @Inject(method = "lambda$new$4", at = @At("HEAD"))
private void flywheel$onEndInitialResourceReload(@Coerce Object gameLoadCookie, Optional error, CallbackInfo ci) {
ModLoader.postEvent(new EndClientResourceReloadEvent((Minecraft) (Object) this, resourceManager, true, error));
}
- @Inject(method = "lambda$reloadResourcePacks$21", at = @At("HEAD"), remap = false)
+ @Inject(method = "lambda$reloadResourcePacks$0", at = @At("HEAD"))
private void flywheel$onEndManualResourceReload(boolean recovery, @Coerce Object gameLoadCookie, CompletableFuture completablefuture, Optional error, CallbackInfo ci) {
ModLoader.postEvent(new EndClientResourceReloadEvent((Minecraft) (Object) this, resourceManager, false, error));
}
diff --git a/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/neoforge/ModelBlockRendererMixin.java b/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/neoforge/ModelBlockRendererMixin.java
index dd5783e8a..e9c123f4d 100644
--- a/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/neoforge/ModelBlockRendererMixin.java
+++ b/neoforge/src/main/java/dev/engine_room/flywheel/impl/mixin/neoforge/ModelBlockRendererMixin.java
@@ -2,29 +2,34 @@
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
-import com.mojang.blaze3d.vertex.PoseStack;
-import com.mojang.blaze3d.vertex.VertexConsumer;
+import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
+import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
+import com.llamalad7.mixinextras.sugar.Local;
-import dev.engine_room.flywheel.lib.model.baked.NeoforgeMeshEmitter;
-import net.minecraft.client.renderer.RenderType;
+import dev.engine_room.flywheel.lib.model.baked.BlockStateModelBufferer;
+import dev.engine_room.flywheel.lib.model.baked.NeoForgeMeshEmitter;
+import dev.engine_room.flywheel.lib.model.baked.NeoForgeMeshEmitterManager;
+import net.minecraft.client.renderer.block.BlockAndTintGetter;
+import net.minecraft.client.renderer.block.BlockQuadOutput;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
-import net.minecraft.client.resources.model.BakedModel;
+import net.minecraft.client.renderer.chunk.ChunkSectionLayer;
+import net.minecraft.client.resources.model.geometry.BakedQuad;
import net.minecraft.core.BlockPos;
-import net.minecraft.util.RandomSource;
-import net.minecraft.world.level.BlockAndTintGetter;
import net.minecraft.world.level.block.state.BlockState;
-import net.neoforged.neoforge.client.model.data.ModelData;
@Mixin(ModelBlockRenderer.class)
abstract class ModelBlockRendererMixin {
- @Inject(method = "tesselateBlock(Lnet/minecraft/world/level/BlockAndTintGetter;Lnet/minecraft/client/resources/model/BakedModel;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;ZLnet/minecraft/util/RandomSource;JILnet/neoforged/neoforge/client/model/data/ModelData;Lnet/minecraft/client/renderer/RenderType;)V", at = @At(value = "INVOKE", target = "net/minecraft/world/level/block/state/BlockState.getOffset(Lnet/minecraft/world/level/BlockGetter;Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/phys/Vec3;"), locals = LocalCapture.CAPTURE_FAILSOFT, require = 0)
- private void onTesselateBlock(BlockAndTintGetter level, BakedModel model, BlockState state, BlockPos pos, PoseStack poseStack, VertexConsumer consumer, boolean checkSides, RandomSource random, long seed, int packedOverlay, ModelData modelData, RenderType renderType, CallbackInfo ci, boolean ao) {
- if (consumer instanceof NeoforgeMeshEmitter meshEmitter) {
- meshEmitter.prepareForModelLayer(ao);
+ @WrapOperation(method = "tesselateAmbientOcclusion", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/ModelBlockRenderer;putQuadWithTint(Lnet/minecraft/client/renderer/block/BlockQuadOutput;FFFLnet/minecraft/client/renderer/block/BlockAndTintGetter;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/client/resources/model/geometry/BakedQuad;)V"))
+ private void onTesselateWithAO(ModelBlockRenderer instance, BlockQuadOutput output, float x, float y, float z, BlockAndTintGetter level, BlockState state, BlockPos pos, BakedQuad quad, Operation original, @Local(name = "ao") boolean ao) {
+ ScopedValue value = BlockStateModelBufferer.EMITTER_MANAGER;
+ if (value.isBound()) {
+ ChunkSectionLayer layer = quad.materialInfo().layer();
+ NeoForgeMeshEmitter meshEmitter = value.get().getEmitter(layer);
+
+ meshEmitter.prepareForPart(ao);
}
+
+ original.call(instance, output, x, y, z, level, state, pos, quad);
}
}
diff --git a/neoforge/src/main/resources/META-INF/accesstransformer.cfg b/neoforge/src/main/resources/META-INF/accesstransformer.cfg
new file mode 100644
index 000000000..0ca9f7400
--- /dev/null
+++ b/neoforge/src/main/resources/META-INF/accesstransformer.cfg
@@ -0,0 +1 @@
+public com.mojang.blaze3d.opengl.GlDevice
diff --git a/neoforge/src/main/resources/META-INF/neoforge.mods.toml b/neoforge/src/main/resources/META-INF/neoforge.mods.toml
index 28a8cd00e..690a25209 100644
--- a/neoforge/src/main/resources/META-INF/neoforge.mods.toml
+++ b/neoforge/src/main/resources/META-INF/neoforge.mods.toml
@@ -5,15 +5,18 @@ license = "${mod_license}"
issueTrackerURL = "${mod_issues}"
[[mods]]
-modId = "${flywheel_id}"
-version = "${flywheel_version}"
-displayName = "${flywheel_name}"
-description = "${flywheel_description}"
+modId = "${mod_id}"
+version = "${mod_version}"
+displayName = "${mod_name}"
+description = "${mod_description}"
logoFile = "logo.png"
-authors = "Jozufozu, PepperCode1"
+authors = "${mod_authors}"
displayURL = "${mod_homepage}"
displayTest = "IGNORE_ALL_VERSION"
+[[accessTransformers]]
+file="accesstransformer.cfg"
+
[[mixins]]
config = "flywheel.backend.mixins.json"
[[mixins]]
@@ -21,26 +24,14 @@ config = "flywheel.impl.mixins.json"
[[mixins]]
config = "flywheel.impl.neoforge.mixins.json"
-[[dependencies.${ flywheel_id }]]
+[[dependencies."${mod_id}"]]
modId = "minecraft"
type = "required"
-versionRange = "${minecraft_maven_version_range}"
+versionRange = "[${minecraft_version}]"
side = "CLIENT"
-[[dependencies.${ flywheel_id }]]
+[[dependencies."${mod_id}"]]
modId = "neoforge"
type = "required"
-versionRange = "${neoforge_version_range}"
-side = "CLIENT"
-
-[[dependencies.${ flywheel_id }]]
-modId = "embeddium"
-type = "optional"
-versionRange = "[0.3.25,)"
-side = "CLIENT"
-
-[[dependencies.${ flywheel_id }]]
-modId = "sodium"
-type = "optional"
-versionRange = "[0.6.0-beta.2,)"
+versionRange = "[${neoforge_version},)"
side = "CLIENT"
diff --git a/neoforge/src/main/resources/flywheel.impl.neoforge.mixins.json b/neoforge/src/main/resources/flywheel.impl.neoforge.mixins.json
index a9dfae6cf..ce6afcd35 100644
--- a/neoforge/src/main/resources/flywheel.impl.neoforge.mixins.json
+++ b/neoforge/src/main/resources/flywheel.impl.neoforge.mixins.json
@@ -1,9 +1,8 @@
{
"required": true,
"minVersion": "0.8",
- "package" : "dev.engine_room.flywheel.impl.mixin.neoforge",
- "compatibilityLevel": "JAVA_17",
- "refmap": "flywheel.refmap.json",
+ "package": "dev.engine_room.flywheel.impl.mixin.neoforge",
+ "compatibilityLevel": "JAVA_25",
"client": [
"ModelBlockRendererMixin"
],
diff --git a/neoforge/src/main/resources/pack.mcmeta b/neoforge/src/main/resources/pack.mcmeta
deleted file mode 100644
index d0ac22a3a..000000000
--- a/neoforge/src/main/resources/pack.mcmeta
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "pack": {
- "description": "${flywheel_name} resources",
- "pack_format": 34
- }
-}
diff --git a/neoforge/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java b/neoforge/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java
deleted file mode 100644
index 0ecd54a87..000000000
--- a/neoforge/src/testMod/java/dev/engine_room/flywheel/FlywheelTestModClient.java
+++ /dev/null
@@ -1,31 +0,0 @@
-package dev.engine_room.flywheel;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.spongepowered.asm.mixin.MixinEnvironment;
-
-import net.minecraft.client.Minecraft;
-import net.neoforged.fml.common.Mod;
-import net.neoforged.fml.loading.FMLLoader;
-import net.neoforged.neoforge.client.event.ClientTickEvent;
-import net.neoforged.neoforge.common.NeoForge;
-
-@Mod("flywheel_testmod")
-public class FlywheelTestModClient {
- public static final String NAME = "Flywheel Test Mod";
- private static final Logger LOGGER = LoggerFactory.getLogger(NAME);
-
- public FlywheelTestModClient() {
- LOGGER.info("Starting {} on Dist: {}", NAME, FMLLoader.getDist());
-
- NeoForge.EVENT_BUS.addListener((ClientTickEvent.Post e) -> {
- LOGGER.info("Running mixin audit");
- MixinEnvironment.getCurrentEnvironment()
- .audit();
-
- LOGGER.info("Stopping client");
- Minecraft.getInstance()
- .stop();
- });
- }
-}
diff --git a/neoforge/src/testMod/resources/META-INF/neoforge.mods.toml b/neoforge/src/testMod/resources/META-INF/neoforge.mods.toml
deleted file mode 100644
index 20235395d..000000000
--- a/neoforge/src/testMod/resources/META-INF/neoforge.mods.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-modLoader = "javafml"
-loaderVersion = "[0,)"
-license = "${mod_license}"
-
-[[mods]]
-modId = "${flywheel_id}_testmod"
-version = "1.0.0"
-displayName = "${flywheel_name} Test Mod"
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 7e3b2f05f..7e3dba327 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,26 +1,31 @@
pluginManagement {
repositories {
gradlePluginPortal()
- mavenCentral()
- maven("https://maven.neoforged.net/releases/") {
- name = "NeoForged"
- }
- maven("https://maven.architectury.dev/") {
- name = "Architectury"
- }
- maven("https://repo.spongepowered.org/repository/maven-public")
- maven("https://maven.parchmentmc.org")
+ maven("https://maven.fabricmc.net")
}
}
-plugins {
- id("org.gradle.toolchains.foojay-resolver-convention") version("0.9.0")
-}
+rootProject.name = "flywheel"
+
+enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
-rootProject.name = "Flywheel"
+includeBuild("build-logic")
-include("common")
-include("fabric")
-include("neoforge")
-include("vanillinNeoForge")
-include("vanillinFabric")
+rootDir.walkTopDown()
+ .maxDepth(2)
+ .filter { it.isDirectory }
+ .filter { it != rootDir }
+ .filter { it.name != "buildSrc" && it.name != "build-logic" }
+ .filter { it.resolve("build.gradle").exists() || it.resolve("build.gradle.kts").exists() }
+ .forEach {
+ val relativePath = it.toRelativeString(rootDir)
+ .replace(File.separatorChar, '-')
+ val projectName = if (it.parentFile == rootDir) {
+ ":${rootProject.name}-$relativePath"
+ } else {
+ ":${it.parentFile.name}:$relativePath"
+ }
+
+ include(projectName)
+ project(projectName).projectDir = it
+ }
diff --git a/vanillin/common/build.gradle.kts b/vanillin/common/build.gradle.kts
new file mode 100644
index 000000000..fa9f5343e
--- /dev/null
+++ b/vanillin/common/build.gradle.kts
@@ -0,0 +1,28 @@
+plugins {
+ alias(libs.plugins.flywheel.gradle)
+ alias(libs.plugins.configure.base)
+ alias(libs.plugins.configure.common)
+ alias(libs.plugins.setup.repositories)
+}
+
+val common = projects.flywheelCommon.path
+
+val main = sourceSets.getByName("main")
+
+transitiveSourceSets {
+ sourceSet(main) {
+ compileClasspath(project(common), "api", "lib", "main")
+ outgoing()
+ }
+}
+
+defaultPackageInfos {
+ sources(main)
+}
+
+dependencies {
+ compileOnly(libs.bundles.mixin)
+ annotationProcessor(libs.mixin.extras)
+
+ compileOnly(libs.sodium.fabric.api)
+}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/VanillaVisuals.java
similarity index 80%
rename from common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/VanillaVisuals.java
index db36bc8a1..c116f86ae 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/VanillaVisuals.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/VanillaVisuals.java
@@ -4,7 +4,7 @@
import java.util.List;
import java.util.function.Consumer;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.vanillin.compose.ComposableEntityVisual;
import dev.engine_room.vanillin.compose.ConfiguredElement;
@@ -18,17 +18,13 @@
import dev.engine_room.vanillin.visuals.BellVisual;
import dev.engine_room.vanillin.visuals.BlockDisplayVisual;
import dev.engine_room.vanillin.visuals.ChestVisual;
-import dev.engine_room.vanillin.visuals.ItemDisplayVisual;
-import dev.engine_room.vanillin.visuals.ItemFrameVisual;
-import dev.engine_room.vanillin.visuals.ItemVisual;
import dev.engine_room.vanillin.visuals.MinecartVisual;
import dev.engine_room.vanillin.visuals.ShulkerBoxVisual;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.ModelLayers;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
-import net.minecraft.world.entity.decoration.ItemFrame;
-import net.minecraft.world.entity.vehicle.AbstractMinecart;
+import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
@@ -62,11 +58,12 @@ public static void init() {
builder(EntityType.BLOCK_DISPLAY).factory(BlockDisplayVisual::new)
.apply(STABLE);
- composable(EntityType.ITEM_DISPLAY).with(element(VisualElements.ITEM_DISPLAY).build())
- .shouldVisualize((ctx, e) -> ItemDisplayVisual.shouldVisualize(e))
- .build()
- .skipVanillaRender(ItemDisplayVisual::shouldVisualize)
- .apply(EXPERIMENTAL);
+ // FIXME 1.21.11: port
+// composable(EntityType.ITEM_DISPLAY).with(element(VisualElements.ITEM_DISPLAY).build())
+// .shouldVisualize((ctx, e) -> ItemDisplayVisual.shouldVisualize(e))
+// .build()
+// .skipVanillaRender(ItemDisplayVisual::shouldVisualize)
+// .apply(EXPERIMENTAL);
minecart(EntityType.CHEST_MINECART, ModelLayers.CHEST_MINECART)
.apply(STABLE);
@@ -90,18 +87,20 @@ public static void init() {
.skipVanillaRender(MinecartVisual::shouldSkipRender)
.apply(STABLE);
- itemFrame(EntityType.ITEM_FRAME).apply(EXPERIMENTAL);
- itemFrame(EntityType.GLOW_ITEM_FRAME).apply(EXPERIMENTAL);
-
- composable(EntityType.ITEM).apply(VanillaVisuals::commonElements)
- .with(element(VisualElements.FIRE).build())
- .with(element(VisualElements.SHADOW).configure(new ShadowElement.Config(0.15f, 0.75f))
- .build())
- .with(element(VisualElements.ITEM_ENTITY).build())
- .shouldVisualize(((ctx, entity) -> ItemVisual.isSupported(entity)))
- .build()
- .skipVanillaRender(ItemVisual::isSupported)
- .apply(EXPERIMENTAL);
+ // FIXME 1.21.11: port
+// itemFrame(EntityType.ITEM_FRAME).apply(EXPERIMENTAL);
+// itemFrame(EntityType.GLOW_ITEM_FRAME).apply(EXPERIMENTAL);
+
+ // FIXME 1.21.11: port
+// composable(EntityType.ITEM).apply(VanillaVisuals::commonElements)
+// .with(element(VisualElements.FIRE).build())
+// .with(element(VisualElements.SHADOW).configure(new ShadowElement.Config(0.15f, 0.75f))
+// .build())
+// .with(element(VisualElements.ITEM_ENTITY).build())
+// .shouldVisualize(((ctx, entity) -> ItemVisual.isSupported(entity)))
+// .build()
+// .skipVanillaRender(ItemVisual::isSupported)
+// .apply(EXPERIMENTAL);
}
@@ -110,13 +109,14 @@ public static void commonElements(EntityBuilder builder) {
.build());
}
- public static EntityVisualizerBuilder itemFrame(EntityType type) {
- return composable(type).apply(VanillaVisuals::commonElements)
- .with(element(VisualElements.ITEM_FRAME).build())
- .shouldVisualize((ctx, entity) -> ItemFrameVisual.shouldVisualize(entity))
- .build()
- .skipVanillaRender(ItemFrameVisual::shouldVisualize);
- }
+ // FIXME 1.21.11: port
+// public static EntityVisualizerBuilder itemFrame(EntityType type) {
+// return composable(type).apply(VanillaVisuals::commonElements)
+// .with(element(VisualElements.ITEM_FRAME).build())
+// .shouldVisualize((ctx, entity) -> ItemFrameVisual.shouldVisualize(entity))
+// .build()
+// .skipVanillaRender(ItemFrameVisual::shouldVisualize);
+// }
public static EntityVisualizerBuilder minecart(EntityType type, ModelLayerLocation variant) {
return composable(type).apply(VanillaVisuals::commonElements)
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/Vanillin.java
similarity index 67%
rename from common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/Vanillin.java
index b6685402c..5c4d8c3d6 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/Vanillin.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/Vanillin.java
@@ -3,7 +3,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.resources.Identifier;
public class Vanillin {
public static final String ID = "vanillin";
@@ -11,7 +11,7 @@ public class Vanillin {
public static final Logger LOGGER = LoggerFactory.getLogger(ID);
public static final Logger CONFIG_LOGGER = LoggerFactory.getLogger(ID + "/config");
- public static ResourceLocation rl(String path) {
- return ResourceLocation.fromNamespaceAndPath(ID, path);
+ public static Identifier id(String path) {
+ return Identifier.fromNamespaceAndPath(ID, path);
}
}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/VanillinXplat.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/VanillinXplat.java
similarity index 65%
rename from common/src/vanillin/java/dev/engine_room/vanillin/VanillinXplat.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/VanillinXplat.java
index 5234e9128..ff1305a3a 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/VanillinXplat.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/VanillinXplat.java
@@ -1,17 +1,11 @@
package dev.engine_room.vanillin;
-import org.jetbrains.annotations.Nullable;
-
import dev.engine_room.flywheel.api.internal.DependencyInjection;
-import net.minecraft.client.color.item.ItemColor;
-import net.minecraft.world.item.Item;
public interface VanillinXplat {
VanillinXplat INSTANCE = DependencyInjection.load(VanillinXplat.class, "dev.engine_room.vanillin.VanillinXplatImpl");
boolean isDevelopmentEnvironment();
- @Nullable ItemColor itemColors(Item item);
-
boolean isModLoaded(String modId);
}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/VisualElements.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/VisualElements.java
similarity index 65%
rename from common/src/vanillin/java/dev/engine_room/vanillin/VisualElements.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/VisualElements.java
index 07ce6c628..2982e213c 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/VisualElements.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/VisualElements.java
@@ -5,18 +5,13 @@
import dev.engine_room.vanillin.elements.HitboxElement;
import dev.engine_room.vanillin.elements.ShadowElement;
import dev.engine_room.vanillin.visuals.BlockDisplayVisual;
-import dev.engine_room.vanillin.visuals.ItemDisplayVisual;
-import dev.engine_room.vanillin.visuals.ItemFrameVisual;
-import dev.engine_room.vanillin.visuals.ItemVisual;
import dev.engine_room.vanillin.visuals.MinecartVisual;
import dev.engine_room.vanillin.visuals.TntMinecartVisual;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.world.entity.Display;
import net.minecraft.world.entity.Entity;
-import net.minecraft.world.entity.decoration.ItemFrame;
-import net.minecraft.world.entity.item.ItemEntity;
-import net.minecraft.world.entity.vehicle.AbstractMinecart;
-import net.minecraft.world.entity.vehicle.MinecartTNT;
+import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart;
+import net.minecraft.world.entity.vehicle.minecart.MinecartTNT;
// TODO: A way to get other elements in a visual, likely using these as keys.
public class VisualElements {
@@ -24,10 +19,12 @@ public class VisualElements {
public static final VisualElement SHADOW = ShadowElement::new;
public static final VisualElement.Unit FIRE = FireElement::new;
- public static final VisualElement.Unit ITEM_ENTITY = ItemVisual::new;
- public static final VisualElement.Unit ITEM_DISPLAY = ItemDisplayVisual::new;
+ // FIXME 1.21.11: port
+// public static final VisualElement.Unit ITEM_ENTITY = ItemVisual::new;
+// public static final VisualElement.Unit ITEM_DISPLAY = ItemDisplayVisual::new;
public static final VisualElement.Unit BLOCK_DISPLAY = BlockDisplayVisual::new;
- public static final VisualElement.Unit ITEM_FRAME = ItemFrameVisual::new;
+ // FIXME 1.21.11: port
+// public static final VisualElement.Unit ITEM_FRAME = ItemFrameVisual::new;
public static final VisualElement MINECART = MinecartVisual::new;
public static final VisualElement.Unit TNT_MINECART = TntMinecartVisual::new;
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java
similarity index 98%
rename from common/src/vanillin/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java
index 3f46ad8d1..8323cba84 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/compose/ComposableEntityVisual.java
@@ -1,6 +1,6 @@
package dev.engine_room.vanillin.compose;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
import dev.engine_room.flywheel.api.visual.EntityVisual;
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElement.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/compose/ConfiguredElement.java
similarity index 100%
rename from common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElement.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/compose/ConfiguredElement.java
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java
similarity index 97%
rename from common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java
index e91b4fb20..d926ae51b 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/compose/ConfiguredElementImpl.java
@@ -2,7 +2,7 @@
import java.util.Objects;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visual.Visual;
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/compose/VisualElement.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/compose/VisualElement.java
similarity index 100%
rename from common/src/vanillin/java/dev/engine_room/vanillin/compose/VisualElement.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/compose/VisualElement.java
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/compose/VisualizationPredicate.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/compose/VisualizationPredicate.java
similarity index 100%
rename from common/src/vanillin/java/dev/engine_room/vanillin/compose/VisualizationPredicate.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/compose/VisualizationPredicate.java
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java
similarity index 94%
rename from common/src/vanillin/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java
index 8c8070999..f2ea30d43 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/BlockEntityVisualizerBuilder.java
@@ -3,7 +3,7 @@
import java.util.Objects;
import java.util.function.Predicate;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
@@ -13,8 +13,7 @@
public class BlockEntityVisualizerBuilder {
private final Configurator configurator;
private final BlockEntityType type;
- @Nullable
- private SimpleBlockEntityVisualizer.Factory visualFactory;
+ private SimpleBlockEntityVisualizer.@Nullable Factory visualFactory;
@Nullable
private Predicate skipVanillaRender;
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/Configurator.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/Configurator.java
similarity index 99%
rename from common/src/vanillin/java/dev/engine_room/vanillin/config/Configurator.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/config/Configurator.java
index 28e97af02..56dbf61c6 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/config/Configurator.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/Configurator.java
@@ -5,7 +5,7 @@
import java.util.List;
import java.util.Map;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
import dev.engine_room.flywheel.api.visualization.EntityVisualizer;
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java
similarity index 95%
rename from common/src/vanillin/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java
index 6e9a8aa54..0b1cd7dc3 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/EntityVisualizerBuilder.java
@@ -3,7 +3,7 @@
import java.util.Objects;
import java.util.function.Predicate;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer;
import net.minecraft.client.renderer.entity.EntityRenderer;
@@ -18,8 +18,7 @@
public final class EntityVisualizerBuilder {
private final Configurator configurator;
private final EntityType type;
- @Nullable
- private SimpleEntityVisualizer.Factory visualFactory;
+ private SimpleEntityVisualizer.@Nullable Factory visualFactory;
@Nullable
private Predicate skipVanillaRender;
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/ModOverrides.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/ModOverrides.java
similarity index 100%
rename from common/src/vanillin/java/dev/engine_room/vanillin/config/ModOverrides.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/config/ModOverrides.java
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/VisualConfigValue.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/VisualConfigValue.java
similarity index 100%
rename from common/src/vanillin/java/dev/engine_room/vanillin/config/VisualConfigValue.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/config/VisualConfigValue.java
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverride.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/VisualOverride.java
similarity index 100%
rename from common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverride.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/config/VisualOverride.java
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverrideValue.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/VisualOverrideValue.java
similarity index 87%
rename from common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverrideValue.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/config/VisualOverrideValue.java
index 333e060d7..6bb0b0024 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/config/VisualOverrideValue.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/config/VisualOverrideValue.java
@@ -1,6 +1,6 @@
package dev.engine_room.vanillin.config;
-import org.jetbrains.annotations.Nullable;
+import org.jspecify.annotations.Nullable;
public enum VisualOverrideValue {
DEFAULT,
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/elements/FireElement.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/elements/FireElement.java
similarity index 89%
rename from common/src/vanillin/java/dev/engine_room/vanillin/elements/FireElement.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/elements/FireElement.java
index 2a4c44e22..cff79913a 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/elements/FireElement.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/elements/FireElement.java
@@ -21,9 +21,11 @@
import dev.engine_room.flywheel.lib.visual.AbstractVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import dev.engine_room.flywheel.lib.visual.util.SmartRecycler;
-import net.minecraft.client.renderer.LightTexture;
+import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.ModelBakery;
+import net.minecraft.client.resources.model.sprite.SpriteId;
+import net.minecraft.util.LightCoordsUtil;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
@@ -35,11 +37,9 @@ public final class FireElement extends AbstractVisual implements SimpleDynamicVi
.backfaceCulling(false) // Disable backface because we want to be able to flip the model.
.build();
- // Parameterize by the material instead of the sprite
- // because Material#sprite is a surprisingly heavy operation
- // and because sprites are invalidated after a resource reload.
- private static final RendererReloadCache FIRE_MODELS = new RendererReloadCache<>(texture -> {
- return new SingleMeshModel(new FireMesh(texture.sprite()), FIRE_MATERIAL);
+ private static final RendererReloadCache FIRE_MODELS = new RendererReloadCache<>(texture -> {
+ TextureAtlasSprite sprite = Minecraft.getInstance().getAtlasManager().get(texture);
+ return new SingleMeshModel(new FireMesh(sprite), FIRE_MATERIAL);
});
private final Entity entity;
@@ -59,7 +59,7 @@ private TransformedInstance createInstance(Model model) {
TransformedInstance instance = visualizationContext.instancerProvider()
.instancer(InstanceTypes.TRANSFORMED, model)
.createInstance();
- instance.light(LightTexture.FULL_BLOCK);
+ instance.light(LightCoordsUtil.pack(15, 0));
instance.setChanged();
return instance;
}
@@ -96,8 +96,7 @@ private void setupInstances(DynamicVisual.Context context) {
stack.setIdentity();
stack.translate(entityX - renderOrigin.getX(), entityY - renderOrigin.getY(), entityZ - renderOrigin.getZ());
stack.scale(scale, scale, scale);
- stack.mulPose(Axis.YP.rotationDegrees(-context.camera()
- .getYRot()));
+ stack.mulPose(Axis.YP.rotationDegrees(-context.cameraRenderState().yRot));
stack.translate(0.0F, 0.0F, -0.3F + (float) ((int) maxHeight) * 0.02F);
for (int i = 0; y < maxHeight; ++i) {
@@ -157,7 +156,7 @@ private static void writeVertex(MutableVertexList vertexList, int i, float x, fl
vertexList.b(i, 1);
vertexList.u(i, u);
vertexList.v(i, v);
- vertexList.light(i, LightTexture.FULL_BLOCK);
+ vertexList.light(i, LightCoordsUtil.pack(15, 0));
vertexList.normalX(i, 0);
vertexList.normalY(i, 1);
vertexList.normalZ(i, 0);
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/elements/HitboxElement.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/elements/HitboxElement.java
similarity index 92%
rename from common/src/vanillin/java/dev/engine_room/vanillin/elements/HitboxElement.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/elements/HitboxElement.java
index 41dd4b245..c83addedd 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/elements/HitboxElement.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/elements/HitboxElement.java
@@ -12,11 +12,13 @@
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import dev.engine_room.flywheel.lib.visual.util.SmartRecycler;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.LightTexture;
+import net.minecraft.client.gui.components.debug.DebugScreenEntries;
+import net.minecraft.util.LightCoordsUtil;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
+// TODO 1.21.11: vanilla changed hitbox rendering and moved it to the debug renderer system (EntityHitboxDebugRenderer)
public final class HitboxElement implements Visual, SimpleDynamicVisual {
// 010------110
// /| /|
@@ -75,7 +77,7 @@ private TransformedInstance createInstance(Model model) {
TransformedInstance instance = context.instancerProvider()
.instancer(InstanceTypes.TRANSFORMED, model)
.createInstance();
- instance.light(LightTexture.FULL_BLOCK);
+ instance.light(LightCoordsUtil.pack(15, 0));
instance.setChanged();
return instance;
}
@@ -108,8 +110,8 @@ public void animate(float partialTick) {
recycler.resetCount();
var shouldRenderHitBoxes = Minecraft.getInstance()
- .getEntityRenderDispatcher()
- .shouldRenderHitBoxes();
+ .debugEntries
+ .isCurrentlyEnabled(DebugScreenEntries.ENTITY_HITBOXES);
if (shouldRenderHitBoxes && !entity.isInvisible() && !Minecraft.getInstance()
.showOnlyReducedInfo()) {
double entityX = Mth.lerp(partialTick, entity.xOld, entity.getX());
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/elements/ShadowElement.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/elements/ShadowElement.java
similarity index 95%
rename from common/src/vanillin/java/dev/engine_room/vanillin/elements/ShadowElement.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/elements/ShadowElement.java
index 8b08b99ab..9bf9fafbb 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/elements/ShadowElement.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/elements/ShadowElement.java
@@ -1,8 +1,8 @@
package dev.engine_room.vanillin.elements;
-import org.jetbrains.annotations.Nullable;
import org.joml.Vector4f;
import org.joml.Vector4fc;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.material.Material;
import dev.engine_room.flywheel.api.material.Transparency;
@@ -20,12 +20,13 @@
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import dev.engine_room.flywheel.lib.visual.util.InstanceRecycler;
import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.LightTexture;
+import net.minecraft.client.renderer.Lightmap;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.core.BlockPos;
import net.minecraft.core.BlockPos.MutableBlockPos;
import net.minecraft.core.Direction.Axis;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.resources.Identifier;
+import net.minecraft.util.LightCoordsUtil;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.RenderShape;
@@ -43,7 +44,7 @@
* The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.
*/
public final class ShadowElement extends AbstractVisual implements SimpleDynamicVisual {
- private static final ResourceLocation SHADOW_TEXTURE = ResourceLocation.withDefaultNamespace("textures/misc/shadow.png");
+ private static final Identifier SHADOW_TEXTURE = Identifier.withDefaultNamespace("textures/misc/shadow.png");
private static final Material SHADOW_MATERIAL = SimpleMaterial.builder()
.texture(SHADOW_TEXTURE)
.mipmap(false)
@@ -157,7 +158,7 @@ private void setupInstance(ChunkAccess chunk, MutableBlockPos pos, double entity
// Too dark to render.
return;
}
- float blockBrightness = LightTexture.getBrightness(level.dimensionType(), maxLocalRawBrightness);
+ float blockBrightness = Lightmap.getBrightness(level.dimensionType(), maxLocalRawBrightness);
float alpha = strength * 0.5F * blockBrightness;
if (alpha < 0.0F) {
// Too far away/too weak to render.
@@ -261,7 +262,7 @@ private static void writeVertex(MutableVertexList vertexList, int i, float x, fl
vertexList.b(i, 1);
vertexList.u(i, 0);
vertexList.v(i, 0);
- vertexList.light(i, LightTexture.FULL_BRIGHT);
+ vertexList.light(i, LightCoordsUtil.FULL_BRIGHT);
vertexList.overlay(i, OverlayTexture.NO_OVERLAY);
vertexList.normalX(i, 0);
vertexList.normalY(i, 1);
diff --git a/vanillin/common/src/main/java/dev/engine_room/vanillin/item/ItemModels.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/item/ItemModels.java
new file mode 100644
index 000000000..cf122ba00
--- /dev/null
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/item/ItemModels.java
@@ -0,0 +1,301 @@
+// FIXME 1.21.11: port
+//package dev.engine_room.vanillin.item;
+//
+//import java.nio.ByteBuffer;
+//import java.nio.IntBuffer;
+//import java.util.ArrayList;
+//import java.util.HashSet;
+//import java.util.List;
+//import java.util.Set;
+//
+//import org.joml.Matrix3f;
+//import org.joml.Matrix4f;
+//import org.joml.Vector3f;
+//import org.joml.Vector4f;
+//import org.jspecify.annotations.Nullable;
+//import org.lwjgl.system.MemoryStack;
+//
+//import com.mojang.blaze3d.vertex.DefaultVertexFormat;
+//import com.mojang.blaze3d.vertex.PoseStack;
+//
+//import dev.engine_room.flywheel.api.material.Material;
+//import dev.engine_room.flywheel.api.material.Transparency;
+//import dev.engine_room.flywheel.api.model.Mesh;
+//import dev.engine_room.flywheel.api.model.Model;
+//import dev.engine_room.flywheel.lib.material.Materials;
+//import dev.engine_room.flywheel.lib.material.SimpleMaterial;
+//import dev.engine_room.flywheel.lib.memory.MemoryBlock;
+//import dev.engine_room.flywheel.lib.model.ModelUtil;
+//import dev.engine_room.flywheel.lib.model.SimpleModel;
+//import dev.engine_room.flywheel.lib.model.SimpleQuadMesh;
+//import dev.engine_room.flywheel.lib.model.SingleMeshModel;
+//import dev.engine_room.flywheel.lib.util.RendererReloadCache;
+//import dev.engine_room.flywheel.lib.vertex.FullVertexView;
+//import dev.engine_room.vanillin.Vanillin;
+//import dev.engine_room.vanillin.VanillinXplat;
+//import dev.engine_room.vanillin.mixin.item.ItemOverridesAccessor;
+//import net.minecraft.client.Minecraft;
+//import net.minecraft.client.multiplayer.ClientLevel;
+//import net.minecraft.client.renderer.ItemBlockRenderTypes;
+//import net.minecraft.client.renderer.block.model.BakedQuad;
+//import net.minecraft.client.renderer.block.model.ItemOverrides;
+//import net.minecraft.client.renderer.item.ItemModel;
+//import net.minecraft.client.renderer.texture.OverlayTexture;
+//import net.minecraft.client.resources.model.BakedModel;
+//import net.minecraft.client.resources.model.ModelResourceLocation;
+//import net.minecraft.client.resources.model.MultiPartBakedModel;
+//import net.minecraft.client.resources.model.SimpleBakedModel;
+//import net.minecraft.client.resources.model.WeightedBakedModel;
+//import net.minecraft.core.Direction;
+//import net.minecraft.core.component.DataComponents;
+//import net.minecraft.core.registries.Registries;
+//import net.minecraft.data.models.ItemModelGenerators;
+//import net.minecraft.resources.ResourceLocation;
+//import net.minecraft.tags.TagKey;
+//import net.minecraft.util.RandomSource;
+//import net.minecraft.world.item.BlockItem;
+//import net.minecraft.world.item.Item;
+//import net.minecraft.world.item.ItemDisplayContext;
+//import net.minecraft.world.item.ItemStack;
+//import net.minecraft.world.item.Items;
+//import net.minecraft.world.level.Level;
+//import net.minecraft.world.level.block.HalfTransparentBlock;
+//import net.minecraft.world.level.block.StainedGlassPaneBlock;
+//
+//public class ItemModels {
+// public static final TagKey- NO_INSTANCING = TagKey.create(Registries.ITEM, Vanillin.id("no_instancing"));
+//
+// private static final Model EMPTY_MODEL = new SimpleModel(List.of());
+// private static final RendererReloadCache MESH_CACHE = new RendererReloadCache<>(key -> bakeMesh(key.model(), key.displayContext()));
+// private static final RendererReloadCache MODEL_CACHE = new RendererReloadCache<>(key -> bakeModel(key.model(), key.displayContext(), key.material(), key.foil()));
+//
+// private static final ModelResourceLocation TRIDENT_MODEL = ModelResourceLocation.vanilla("trident", "inventory");
+// private static final ModelResourceLocation SPYGLASS_MODEL = ModelResourceLocation.vanilla("spyglass", "inventory");
+//
+// private static final @Nullable Direction[] DIRECTIONS = new Direction[]{Direction.DOWN, Direction.UP, Direction.NORTH, Direction.SOUTH, Direction.WEST, Direction.EAST, null};
+//
+// private static final Set ALLOWED_OVERRIDES = new HashSet<>();
+//
+// static {
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("lefthanded"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("cooldown"));
+// ALLOWED_OVERRIDES.add(ItemModelGenerators.TRIM_TYPE_PREDICATE_ID);
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("custom_model_data"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("pull"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("brushing"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("pulling"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("filled"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("charged"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("firework"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("broken"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("cast"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("blocking"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("throwing"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("level"));
+// ALLOWED_OVERRIDES.add(ResourceLocation.withDefaultNamespace("tooting"));
+// }
+//
+// public static boolean isSupported(ItemStack stack) {
+// return !stack.is(NO_INSTANCING) && doesNotHaveItemColors(stack.getItem()) && isSupported(getModel(stack));
+// }
+//
+// private static boolean doesNotHaveItemColors(Item item) {
+// return VanillinXplat.INSTANCE.itemColors(item) == null;
+// }
+//
+// public static ItemModel getModel(ItemStack stack) {
+// return Minecraft.getInstance()
+// .getModelManager()
+// .getItemModel(stack.get(DataComponents.ITEM_MODEL));
+// }
+//
+// @Nullable
+// public static BakedModel getActualBakedModel(@Nullable ClientLevel clientLevel, ItemStack itemStack, ItemDisplayContext displayContext) {
+// if (itemStack.isEmpty()) {
+// return null;
+// }
+//
+// var baseModel = getModel(itemStack);
+// var overrides = baseModel.getOverrides();
+// var model = overrides.resolve(baseModel, itemStack, clientLevel, null, 0);
+//
+// if (model == null) {
+// model = baseModel;
+// }
+//
+// boolean notEquipped = displayContext == ItemDisplayContext.GUI || displayContext == ItemDisplayContext.GROUND || displayContext == ItemDisplayContext.FIXED;
+// if (model.isCustomRenderer() || itemStack.is(Items.TRIDENT) && !notEquipped) {
+// return null;
+// }
+//
+// if (notEquipped) {
+// if (itemStack.is(Items.TRIDENT)) {
+// model = Minecraft.getInstance()
+// .getItemRenderer()
+// .getItemModelShaper()
+// .getModelManager()
+// .getModel(TRIDENT_MODEL);
+// } else if (itemStack.is(Items.SPYGLASS)) {
+// model = Minecraft.getInstance()
+// .getItemRenderer()
+// .getItemModelShaper()
+// .getModelManager()
+// .getModel(SPYGLASS_MODEL);
+// }
+// }
+//
+// return model;
+// }
+//
+// public static boolean isSupported(BakedModel model) {
+// if (model.isCustomRenderer()) {
+// return false;
+// }
+//
+// var overrides = model.getOverrides();
+// if (overrides != ItemOverrides.EMPTY) {
+// var properties = ((ItemOverridesAccessor) overrides).vanillin$properties();
+//
+// for (var property : properties) {
+// if (!ALLOWED_OVERRIDES.contains(property)) {
+// return false;
+// }
+// }
+// }
+//
+// // Check for class equality rather than instanceof to ensure subclasses are *not* handled by vanillin.
+// Class extends BakedModel> c = model.getClass();
+// if (!(c == SimpleBakedModel.class || c == MultiPartBakedModel.class || c == WeightedBakedModel.class)) {
+// return false;
+// }
+//
+// return true;
+// }
+//
+// public static Model get(Level level, ItemStack itemStack, ItemDisplayContext displayContext) {
+// boolean cull = displayContext == ItemDisplayContext.GUI || displayContext.firstPerson() || !(itemStack.getItem() instanceof BlockItem block) || !(block.getBlock() instanceof HalfTransparentBlock) && !(block.getBlock() instanceof StainedGlassPaneBlock);
+// var material = ModelUtil.getItemMaterial(ItemBlockRenderTypes.getRenderType(itemStack, cull));
+//
+// if (material == null) {
+// material = Materials.TRANSLUCENT_ENTITY;
+// }
+//
+// if (itemStack.getItem() instanceof BlockItem && material.transparency() == Transparency.TRANSLUCENT) {
+// material = SimpleMaterial.builderOf(material)
+// .transparency(Transparency.ORDER_INDEPENDENT)
+// .build();
+// }
+//
+// // Visuals all hold references to Level so use that as the parameter type for convenience and cast here.
+// ClientLevel clientLevel = (level instanceof ClientLevel) ? (ClientLevel) level : null;
+//
+// BakedModel model = getActualBakedModel(clientLevel, itemStack, displayContext);
+//
+// if (model == null) {
+// return EMPTY_MODEL;
+// }
+//
+// return MODEL_CACHE.get(new BakedModelKey(model, displayContext, material, itemStack.hasFoil()));
+// }
+//
+// public static Model bakeModel(BakedModel model, ItemDisplayContext displayContext, Material material, boolean foil) {
+// var mesh = MESH_CACHE.get(new BakedMeshKey(model, displayContext));
+//
+// if (foil) {
+// return new SimpleModel(List.of(new Model.ConfiguredMesh(material, mesh), new Model.ConfiguredMesh(Materials.GLINT, mesh)));
+// } else {
+// return new SingleMeshModel(mesh, material);
+// }
+// }
+//
+// public static Mesh bakeMesh(BakedModel model, ItemDisplayContext displayContext) {
+// boolean leftHand = displayContext == ItemDisplayContext.FIRST_PERSON_LEFT_HAND || displayContext == ItemDisplayContext.THIRD_PERSON_LEFT_HAND;
+//
+// var poseStack = new PoseStack();
+//
+// model.getTransforms()
+// .getTransform(displayContext)
+// .apply(leftHand, poseStack);
+// poseStack.translate(-0.5f, -0.5f, -0.5f);
+//
+// RandomSource randomSource = RandomSource.create();
+//
+// // Write all BakedQuads into a list first to get a count so we can allocate memory ahead of time.
+// List allQuads = new ArrayList<>();
+// for (Direction value : DIRECTIONS) {
+// randomSource.setSeed(42L);
+// allQuads.addAll(model.getQuads(null, value, randomSource));
+// }
+//
+// int vertexCount = allQuads.size() * 4;
+// var memoryBlock = MemoryBlock.mallocTracked(vertexCount * FullVertexView.STRIDE);
+// var meshVertices = new FullVertexView();
+//
+// meshVertices.nativeMemoryOwner(memoryBlock);
+// meshVertices.ptr(memoryBlock.ptr());
+// meshVertices.vertexCount(vertexCount);
+//
+// Vector4f position = new Vector4f();
+// Vector3f normal = new Vector3f();
+//
+// Matrix4f poseMatrix = poseStack.last()
+// .pose();
+// Matrix3f normalMatrix = poseStack.last()
+// .normal();
+//
+// try (MemoryStack memoryStack = MemoryStack.stackPush();) {
+// ByteBuffer byteBuffer = memoryStack.malloc(DefaultVertexFormat.BLOCK.getVertexSize());
+// IntBuffer intBuffer = byteBuffer.asIntBuffer();
+//
+// int vertex = 0;
+//
+// for (BakedQuad quad : allQuads) {
+// SodiumAnimatedTextureCompat.add(quad.getSprite());
+//
+// int[] js = quad.getVertices();
+// var direction = quad.getDirection();
+//
+// normal.set(direction.getStepX(), direction.getStepY(), direction.getStepZ());
+// normal.mul(normalMatrix);
+//
+// int j = js.length / 8;
+//
+// for (int k = 0; k < j; ++k) {
+// intBuffer.clear();
+// intBuffer.put(js, k * 8, 8);
+//
+// position.set(byteBuffer.getFloat(0), byteBuffer.getFloat(4), byteBuffer.getFloat(8), 1.0f);
+// position.mul(poseMatrix);
+//
+// // We could probably handle item colors here.
+// meshVertices.x(vertex, position.x());
+// meshVertices.y(vertex, position.y());
+// meshVertices.z(vertex, position.z());
+// meshVertices.r(vertex, 1.0f);
+// meshVertices.g(vertex, 1.0f);
+// meshVertices.b(vertex, 1.0f);
+// meshVertices.a(vertex, 1.0f);
+// meshVertices.u(vertex, byteBuffer.getFloat(16));
+// meshVertices.v(vertex, byteBuffer.getFloat(20));
+// meshVertices.overlay(vertex, OverlayTexture.NO_OVERLAY);
+// meshVertices.light(vertex, 0);
+// meshVertices.normalX(vertex, normal.x());
+// meshVertices.normalY(vertex, normal.y());
+// meshVertices.normalZ(vertex, normal.z());
+//
+// vertex++;
+// }
+// }
+// }
+//
+// return new SimpleQuadMesh(meshVertices);
+// }
+//
+// public record BakedModelKey(BakedModel model, ItemDisplayContext displayContext, Material material, boolean foil) {
+//
+// }
+//
+// public record BakedMeshKey(BakedModel model, ItemDisplayContext displayContext) {
+//
+// }
+//}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java
similarity index 91%
rename from common/src/vanillin/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java
index 031808fa7..51e1ee30a 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/item/SodiumAnimatedTextureCompat.java
@@ -4,7 +4,7 @@
import it.unimi.dsi.fastutil.objects.ReferenceArraySet;
import it.unimi.dsi.fastutil.objects.ReferenceSet;
import it.unimi.dsi.fastutil.objects.ReferenceSets;
-import net.caffeinemc.mods.sodium.client.render.texture.SpriteUtil;
+import net.caffeinemc.mods.sodium.api.texture.SpriteUtil;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
/**
@@ -42,14 +42,14 @@ public static void onReloadRenderer() {
private static final class Internals {
private static void add(TextureAtlasSprite sprite) {
- if (SpriteUtil.hasAnimation(sprite)) {
+ if (SpriteUtil.INSTANCE.hasAnimation(sprite)) {
VISIBLE.add(sprite);
}
}
private static void beginFrame() {
for (var sprite : VISIBLE) {
- SpriteUtil.markSpriteActive(sprite);
+ SpriteUtil.INSTANCE.markSpriteActive(sprite);
}
}
}
diff --git a/vanillin/common/src/main/java/dev/engine_room/vanillin/mixin/BlockModelSetAccessor.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/mixin/BlockModelSetAccessor.java
new file mode 100644
index 000000000..fc531a9de
--- /dev/null
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/mixin/BlockModelSetAccessor.java
@@ -0,0 +1,16 @@
+package dev.engine_room.vanillin.mixin;
+
+import java.util.Map;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import net.minecraft.client.renderer.block.BlockModelSet;
+import net.minecraft.client.renderer.block.model.BlockModel;
+import net.minecraft.world.level.block.state.BlockState;
+
+@Mixin(BlockModelSet.class)
+public interface BlockModelSetAccessor {
+ @Accessor("blockModelByStateCache")
+ Map flywheel$getBlockModelByStateCache();
+}
diff --git a/vanillin/common/src/main/java/dev/engine_room/vanillin/mixin/ChestRendererAccessor.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/mixin/ChestRendererAccessor.java
new file mode 100644
index 000000000..754e65302
--- /dev/null
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/mixin/ChestRendererAccessor.java
@@ -0,0 +1,16 @@
+package dev.engine_room.vanillin.mixin;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Invoker;
+
+import net.minecraft.client.renderer.blockentity.ChestRenderer;
+import net.minecraft.client.renderer.blockentity.state.ChestRenderState;
+import net.minecraft.world.level.block.entity.BlockEntity;
+
+@Mixin(ChestRenderer.class)
+public interface ChestRendererAccessor {
+ @Invoker("getChestMaterial")
+ static ChestRenderState.ChestMaterialType flywheel$getChestMaterial(BlockEntity blockEntity, boolean xmasTextures) {
+ throw new AssertionError();
+ }
+}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BellVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/BellVisual.java
similarity index 97%
rename from common/src/vanillin/java/dev/engine_room/vanillin/visuals/BellVisual.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/BellVisual.java
index cd6788c67..7f52c22bf 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BellVisual.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/BellVisual.java
@@ -34,7 +34,7 @@ public class BellVisual extends AbstractBlockEntityVisual imple
public BellVisual(VisualizationContext ctx, BellBlockEntity blockEntity, float partialTick) {
super(ctx, blockEntity, partialTick);
- instances = InstanceTree.create(instancerProvider(), ModelTrees.of(ModelLayers.BELL, BellRenderer.BELL_RESOURCE_LOCATION, MATERIAL));
+ instances = InstanceTree.create(instancerProvider(), ModelTrees.of(ModelLayers.BELL, BellRenderer.BELL_TEXTURE, MATERIAL));
bellBody = instances.childOrThrow("bell_body");
BlockPos visualPos = getVisualPosition();
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java
similarity index 81%
rename from common/src/vanillin/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java
index 212e8bb82..12d7b53bc 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/BlockDisplayVisual.java
@@ -9,9 +9,10 @@
import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import dev.engine_room.flywheel.lib.visual.component.ShadowComponent;
-import net.minecraft.client.Camera;
+import net.minecraft.client.renderer.state.level.CameraRenderState;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Display;
+import net.minecraft.world.entity.Display.RenderState;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
@@ -41,7 +42,7 @@ public BlockDisplayVisual(VisualizationContext ctx, Display.BlockDisplay entity,
@Override
public void beginFrame(Context ctx) {
- Display.RenderState renderState = entity.renderState();
+ RenderState renderState = entity.renderState();
if (renderState == null) {
instance.handle()
.setVisible(false);
@@ -84,19 +85,19 @@ public void beginFrame(Context ctx) {
.translate((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ()));
float partialTick = ctx.partialTick();
- Camera camera = ctx.camera();
+ CameraRenderState cameraRenderState = ctx.cameraRenderState();
switch (renderState.billboardConstraints()) {
case FIXED:
instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F);
break;
case HORIZONTAL:
- instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * cameraXRot(camera), 0.0F);
+ instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * cameraXRot(cameraRenderState), 0.0F);
break;
case VERTICAL:
- instance.pose.rotateYXZ(-0.017453292F * cameraYrot(camera), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F);
+ instance.pose.rotateYXZ(-0.017453292F * cameraYrot(cameraRenderState), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F);
break;
case CENTER:
- instance.pose.rotateYXZ(-0.017453292F * cameraYrot(camera), ((float) Math.PI / 180F) * cameraXRot(camera), 0.0F);
+ instance.pose.rotateYXZ(-0.017453292F * cameraYrot(cameraRenderState), ((float) Math.PI / 180F) * cameraXRot(cameraRenderState), 0.0F);
break;
}
@@ -106,12 +107,12 @@ public void beginFrame(Context ctx) {
.setChanged();
}
- private static float cameraYrot(Camera camera) {
- return camera.getYRot() - 180.0F;
+ private static float cameraYrot(CameraRenderState cameraRenderState) {
+ return cameraRenderState.yRot - 180.0F;
}
- private static float cameraXRot(Camera camera) {
- return -camera.getXRot();
+ private static float cameraXRot(CameraRenderState cameraRenderState) {
+ return -cameraRenderState.xRot;
}
private static float entityYRot(Entity entity, float partialTick) {
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ChestVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ChestVisual.java
similarity index 84%
rename from common/src/vanillin/java/dev/engine_room/vanillin/visuals/ChestVisual.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ChestVisual.java
index fe4731189..0ac569f78 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ChestVisual.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ChestVisual.java
@@ -1,13 +1,12 @@
package dev.engine_room.vanillin.visuals;
-import java.util.Calendar;
import java.util.EnumMap;
import java.util.Map;
import java.util.function.Consumer;
-import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.joml.Matrix4fc;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.instance.Instance;
import dev.engine_room.flywheel.api.material.Material;
@@ -18,15 +17,18 @@
import dev.engine_room.flywheel.lib.model.part.ModelTrees;
import dev.engine_room.flywheel.lib.visual.AbstractBlockEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
+import dev.engine_room.vanillin.mixin.ChestRendererAccessor;
import it.unimi.dsi.fastutil.floats.Float2FloatFunction;
import it.unimi.dsi.fastutil.longs.LongSet;
import net.minecraft.client.model.geom.ModelLayerLocation;
import net.minecraft.client.model.geom.ModelLayers;
import net.minecraft.client.renderer.LevelRenderer;
-import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.Sheets;
+import net.minecraft.client.renderer.blockentity.ChestRenderer;
+import net.minecraft.client.resources.model.sprite.SpriteId;
import net.minecraft.core.BlockPos;
import net.minecraft.core.SectionPos;
+import net.minecraft.util.LightCoordsUtil;
import net.minecraft.util.Mth;
import net.minecraft.world.level.block.AbstractChestBlock;
import net.minecraft.world.level.block.Block;
@@ -61,8 +63,7 @@ public class ChestVisual extends Abstrac
@Nullable
private final Matrix4fc initialPose;
private final BrightnessCombiner brightnessCombiner = new BrightnessCombiner();
- @Nullable
- private final DoubleBlockCombiner.NeighborCombineResult extends ChestBlockEntity> neighborCombineResult;
+ private final DoubleBlockCombiner.@Nullable NeighborCombineResult extends ChestBlockEntity> neighborCombineResult;
@Nullable
private final Float2FloatFunction lidProgress;
@@ -74,7 +75,10 @@ public ChestVisual(VisualizationContext ctx, T blockEntity, float partialTick) {
Block block = blockState.getBlock();
if (block instanceof AbstractChestBlock> chestBlock) {
ChestType chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE;
- net.minecraft.client.resources.model.Material texture = Sheets.chooseMaterial(blockEntity, chestType, isChristmas());
+ SpriteId texture = Sheets.chooseSprite(
+ ChestRendererAccessor.flywheel$getChestMaterial(blockEntity, ChestRenderer.xmasTextures()),
+ chestType
+ );
instances = InstanceTree.create(instancerProvider(), ModelTrees.of(LAYER_LOCATIONS.get(chestType), texture, MATERIAL));
lid = instances.childOrThrow("lid");
lock = instances.childOrThrow("lock");
@@ -95,11 +99,6 @@ public ChestVisual(VisualizationContext ctx, T blockEntity, float partialTick) {
}
}
- private static boolean isChristmas() {
- Calendar calendar = Calendar.getInstance();
- return calendar.get(Calendar.MONTH) + 1 == 12 && calendar.get(Calendar.DATE) >= 24 && calendar.get(Calendar.DATE) <= 26;
- }
-
private Matrix4f createInitialPose() {
BlockPos visualPos = getVisualPosition();
float horizontalAngle = blockState.getValue(ChestBlock.FACING).toYRot();
@@ -200,23 +199,23 @@ public LongSet acceptNone() {
private class BrightnessCombiner implements DoubleBlockCombiner.Combiner {
@Override
public Integer acceptDouble(BlockEntity first, BlockEntity second) {
- int firstLight = LevelRenderer.getLightColor(first.getLevel(), first.getBlockPos());
- int secondLight = LevelRenderer.getLightColor(second.getLevel(), second.getBlockPos());
- int firstBlockLight = LightTexture.block(firstLight);
- int secondBlockLight = LightTexture.block(secondLight);
- int firstSkyLight = LightTexture.sky(firstLight);
- int secondSkyLight = LightTexture.sky(secondLight);
- return LightTexture.pack(Math.max(firstBlockLight, secondBlockLight), Math.max(firstSkyLight, secondSkyLight));
+ int firstLight = LevelRenderer.getLightCoords(first.getLevel(), first.getBlockPos());
+ int secondLight = LevelRenderer.getLightCoords(second.getLevel(), second.getBlockPos());
+ int firstBlockLight = LightCoordsUtil.block(firstLight);
+ int secondBlockLight = LightCoordsUtil.block(secondLight);
+ int firstSkyLight = LightCoordsUtil.sky(firstLight);
+ int secondSkyLight = LightCoordsUtil.sky(secondLight);
+ return LightCoordsUtil.pack(Math.max(firstBlockLight, secondBlockLight), Math.max(firstSkyLight, secondSkyLight));
}
@Override
public Integer acceptSingle(BlockEntity single) {
- return LevelRenderer.getLightColor(single.getLevel(), single.getBlockPos());
+ return LevelRenderer.getLightCoords(single.getLevel(), single.getBlockPos());
}
@Override
public Integer acceptNone() {
- return LevelRenderer.getLightColor(level, pos);
+ return LevelRenderer.getLightCoords(level, pos);
}
}
}
diff --git a/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java
new file mode 100644
index 000000000..20ddda5ab
--- /dev/null
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemDisplayVisual.java
@@ -0,0 +1,149 @@
+// FIXME 1.21.11: port
+//package dev.engine_room.vanillin.visuals;
+//
+//import java.util.Objects;
+//
+//import org.jspecify.annotations.Nullable;
+//
+//import com.mojang.math.Transformation;
+//
+//import dev.engine_room.flywheel.api.visualization.VisualizationContext;
+//import dev.engine_room.flywheel.lib.instance.InstanceTypes;
+//import dev.engine_room.flywheel.lib.instance.TransformedInstance;
+//import dev.engine_room.flywheel.lib.model.Models;
+//import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual;
+//import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
+//import dev.engine_room.flywheel.lib.visual.component.ShadowComponent;
+//import dev.engine_room.vanillin.item.ItemModels;
+//import net.minecraft.client.Camera;
+//import net.minecraft.util.Mth;
+//import net.minecraft.world.entity.Display;
+//import net.minecraft.world.entity.Entity;
+//import net.minecraft.world.item.ItemStack;
+//import net.minecraft.world.level.block.Blocks;
+//import net.minecraft.world.phys.Vec3;
+//
+//public class ItemDisplayVisual extends AbstractEntityVisual implements SimpleDynamicVisual {
+// private final TransformedInstance instance;
+//
+// private ItemStack currentStack;
+//
+// private final ShadowComponent shadowComponent;
+//
+// public ItemDisplayVisual(VisualizationContext ctx, Display.ItemDisplay entity, float partialTick) {
+// super(ctx, entity, partialTick);
+//
+// var itemRenderState = entity.itemRenderState();
+//
+// if (itemRenderState == null) {
+// currentStack = ItemStack.EMPTY;
+// instance = ctx.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, Models.block(Blocks.AIR.defaultBlockState()))
+// .createInstance();
+// } else {
+// currentStack = itemRenderState.itemStack()
+// .copy();
+// instance = ctx.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, currentStack, itemRenderState.itemTransform()))
+// .createInstance();
+// }
+//
+// shadowComponent = new ShadowComponent(ctx, entity);
+// }
+//
+// @Override
+// public void beginFrame(Context ctx) {
+// Display.RenderState renderState = entity.renderState();
+// if (renderState == null) {
+// instance.handle()
+// .setVisible(false);
+// return;
+// }
+// var object = entity.itemRenderState();
+// if (object == null) {
+// instance.handle()
+// .setVisible(false);
+// return;
+// }
+//
+// instance.handle()
+// .setVisible(true);
+//
+// var itemStack = object.itemStack();
+//
+// if (!ItemStack.matches(itemStack, currentStack)) {
+// currentStack = itemStack.copy();
+// visualizationContext.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, currentStack, object.itemTransform()))
+// .stealInstance(instance);
+// }
+//
+// float f = entity.calculateInterpolationProgress(ctx.partialTick());
+//
+// shadowComponent.radius(renderState.shadowRadius()
+// .get(f));
+// shadowComponent.strength(renderState.shadowStrength()
+// .get(f));
+// shadowComponent.beginFrame(ctx);
+//
+// int i = renderState.brightnessOverride();
+// int j = i != -1 ? i : computePackedLight(ctx.partialTick());
+// Transformation transformation = renderState.transformation()
+// .get(f);
+//
+// Vec3 pos = entity.position();
+// var renderOrigin = renderOrigin();
+//
+// instance.setIdentityTransform()
+// .translate((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ()));
+//
+// float partialTick = ctx.partialTick();
+// Camera cameraRenderState = ctx.cameraRenderState();
+// switch (renderState.billboardConstraints()) {
+// case FIXED:
+// instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F);
+// break;
+// case HORIZONTAL:
+// instance.pose.rotateYXZ(-0.017453292F * entityYRot(entity, partialTick), ((float) Math.PI / 180F) * cameraXRot(cameraRenderState), 0.0F);
+// break;
+// case VERTICAL:
+// instance.pose.rotateYXZ(-0.017453292F * cameraYrot(cameraRenderState), ((float) Math.PI / 180F) * entityXRot(entity, partialTick), 0.0F);
+// break;
+// case CENTER:
+// instance.pose.rotateYXZ(-0.017453292F * cameraYrot(cameraRenderState), ((float) Math.PI / 180F) * cameraXRot(cameraRenderState), 0.0F);
+// break;
+// }
+//
+// // getMatrix does a copy which is not strictly necessary here but oh well.
+// instance.mul(transformation.getMatrix())
+// .rotateY(Mth.PI)
+// .light(j)
+// .setChanged();
+// }
+//
+// private static float cameraYrot(Camera cameraRenderState) {
+// return cameraRenderState.yRot() - 180.0F;
+// }
+//
+// private static float cameraXRot(Camera cameraRenderState) {
+// return -cameraRenderState.xRot();
+// }
+//
+// private static float entityYRot(Entity entity, float partialTick) {
+// return Mth.rotLerp(partialTick, entity.yRotO, entity.getYRot());
+// }
+//
+// private static float entityXRot(Entity entity, float partialTick) {
+// return Mth.lerp(partialTick, entity.xRotO, entity.getXRot());
+// }
+//
+// @Override
+// protected void _delete() {
+// instance.delete();
+// }
+//
+// public static boolean shouldVisualize(Display.ItemDisplay itemDisplay) {
+// var state = itemDisplay.itemRenderState();
+// return state != null && ItemModels.isSupported(state.itemStack());
+// }
+//}
diff --git a/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java
new file mode 100644
index 000000000..2bee5d1ce
--- /dev/null
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemFrameVisual.java
@@ -0,0 +1,174 @@
+// FIXME 1.21.11: port
+//package dev.engine_room.vanillin.visuals;
+//
+//import org.joml.Matrix4f;
+//
+//import dev.engine_room.flywheel.api.model.Model;
+//import dev.engine_room.flywheel.api.visual.EntityVisual;
+//import dev.engine_room.flywheel.api.visualization.VisualizationContext;
+//import dev.engine_room.flywheel.lib.instance.InstanceTypes;
+//import dev.engine_room.flywheel.lib.instance.TransformedInstance;
+//import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
+//import dev.engine_room.flywheel.lib.util.RendererReloadCache;
+//import dev.engine_room.flywheel.lib.visual.AbstractVisual;
+//import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
+//import dev.engine_room.vanillin.item.ItemModels;
+//import net.minecraft.client.Minecraft;
+//import net.minecraft.client.renderer.block.BlockModelShaper;
+//import net.minecraft.client.resources.model.BlockStateDefinitions;
+//import net.minecraft.core.BlockPos;
+//import net.minecraft.core.Direction;
+//import net.minecraft.util.Mth;
+//import net.minecraft.world.entity.EntityType;
+//import net.minecraft.world.entity.decoration.ItemFrame;
+//import net.minecraft.world.item.ItemDisplayContext;
+//import net.minecraft.world.item.ItemStack;
+//import net.minecraft.world.item.Items;
+//import net.minecraft.world.level.LightLayer;
+//import net.minecraft.world.level.block.state.BlockState;
+//
+//public class ItemFrameVisual extends AbstractVisual implements EntityVisual, SimpleDynamicVisual {
+// public static final RendererReloadCache BLOCK_STATE = new RendererReloadCache<>(state -> {
+// BlockModelShaper blockModelShaper = Minecraft.getInstance()
+// .getModelManager()
+// .getBlockModelShaper();
+//
+// return new BlockModelBuilder(blockModelShaper.getBlockModel(state))
+// .build();
+// });
+//
+// private final Matrix4f baseTransform = new Matrix4f();
+//
+// private final TransformedInstance frame;
+// private final TransformedInstance item;
+// private final ItemFrame entity;
+// private BlockState lastFrameBlockState;
+// private ItemStack lastItemStack;
+//
+// public ItemFrameVisual(VisualizationContext ctx, ItemFrame entity, float partialTick) {
+// super(ctx, entity.level(), partialTick);
+//
+// this.entity = entity;
+//
+// lastItemStack = entity.getItem()
+// .copy();
+//
+// lastFrameBlockState = getFrameBlockState(entity, lastItemStack);
+// var frameModel = BLOCK_STATE.get(lastFrameBlockState);
+//
+// frame = ctx.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, frameModel)
+// .createInstance();
+//
+// frame.setTransform(baseTransform);
+//
+// item = ctx.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, lastItemStack, ItemDisplayContext.FIXED))
+// .createInstance();
+//
+// animate(partialTick);
+// }
+//
+// public static boolean shouldVisualize(ItemFrame entity) {
+// // We don't support map rendering, and we can't support exotic item models.
+// return !entity.getItem()
+// .is(Items.FILLED_MAP) && ItemModels.isSupported(entity.getItem());
+// }
+//
+// @Override
+// public void beginFrame(Context ctx) {
+// animate(ctx.partialTick());
+// }
+//
+// public void animate(float partialTick) {
+// var light = LightTexture.pack(getBlockLightLevel(entity.getPos()), getSkyLightLevel(entity.getPos()));
+//
+// boolean invisible = entity.isInvisible();
+//
+// Direction direction = entity.getDirection();
+// var origin = visualizationContext.renderOrigin();
+//
+// float d = 0.46875f;
+//
+// float x = (float) (entity.getX() - origin.getX() + direction.getStepX() * d);
+// float y = (float) (entity.getY() - origin.getY() + direction.getStepY() * d);
+// float z = (float) (entity.getZ() - origin.getZ() + direction.getStepZ() * d);
+//
+// baseTransform.translation(x, y, z);
+// baseTransform.rotateXYZ(Mth.DEG_TO_RAD * entity.getXRot(), Mth.DEG_TO_RAD * (180.0f - entity.getYRot()), 0.0f);
+//
+// var stack = entity.getItem();
+// var frameBlockState = getFrameBlockState(entity, stack);
+//
+// if (frameBlockState != lastFrameBlockState) {
+// visualizationContext.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, BLOCK_STATE.get(frameBlockState))
+// .stealInstance(frame);
+// lastFrameBlockState = frameBlockState;
+// }
+//
+// frame.setVisible(!invisible);
+//
+// frame.setTransform(baseTransform)
+// .translate(-0.5f, -0.5f, -0.5f)
+// .light(light)
+// .setChanged();
+//
+// if (!ItemStack.matches(lastItemStack, stack)) {
+// lastItemStack = stack.copy();
+// visualizationContext.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, ItemModels.get(level, lastItemStack, ItemDisplayContext.FIXED))
+// .stealInstance(item);
+// }
+//
+// item.setTransform(baseTransform);
+//
+// if (invisible) {
+// item.translate(0.0F, 0.0F, 0.5F);
+// } else {
+// item.translate(0.0F, 0.0F, 0.4375F);
+// }
+//
+// int i = entity.hasFramedMap() ? entity.getRotation() % 4 * 2 : entity.getRotation();
+//
+// item.rotateZDegrees(i * 360.0F / 8.0F);
+//
+// item.scale(0.5F, 0.5F, 0.5F);
+//
+// item.light(getLightVal(15728880, light))
+// .setChanged();
+// }
+//
+// @Override
+// public void update(float partialTick) {
+//
+// }
+//
+// @Override
+// protected void _delete() {
+// frame.delete();
+// item.delete();
+// }
+//
+// private int getLightVal(int glowLightVal, int regularLightVal) {
+// return entity.getType() == EntityType.GLOW_ITEM_FRAME ? glowLightVal : regularLightVal;
+// }
+//
+// protected int getSkyLightLevel(BlockPos pos) {
+// return level.getBrightness(LightLayer.SKY, pos);
+// }
+//
+// protected int getBlockLightLevelBase(BlockPos pos) {
+// return entity.isOnFire() ? 15 : level.getBrightness(LightLayer.BLOCK, pos);
+// }
+//
+// protected int getBlockLightLevel(BlockPos pos) {
+// return entity.getType() == EntityType.GLOW_ITEM_FRAME ? Math.max(5, getBlockLightLevelBase(pos)) : getBlockLightLevelBase(pos);
+// }
+//
+// public static BlockState getFrameBlockState(ItemFrame entity, ItemStack item) {
+// boolean isGlowFrame = entity.getType() == EntityType.GLOW_ITEM_FRAME;
+// boolean map = !item.isEmpty() && entity.getFramedMapId(item) != null;
+// return BlockStateDefinitions.getItemFrameFakeState(isGlowFrame, map);
+// }
+//}
diff --git a/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemVisual.java
new file mode 100644
index 000000000..273ee7f21
--- /dev/null
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ItemVisual.java
@@ -0,0 +1,162 @@
+// FIXME 1.21.11: port
+//package dev.engine_room.vanillin.visuals;
+//
+//import com.mojang.blaze3d.vertex.PoseStack;
+//import com.mojang.math.Axis;
+//
+//import dev.engine_room.flywheel.api.visualization.VisualizationContext;
+//import dev.engine_room.flywheel.lib.instance.InstanceTypes;
+//import dev.engine_room.flywheel.lib.instance.TransformedInstance;
+//import dev.engine_room.flywheel.lib.transform.TransformStack;
+//import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual;
+//import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
+//import dev.engine_room.flywheel.lib.visual.util.InstanceRecycler;
+//import dev.engine_room.vanillin.item.ItemModels;
+//import net.minecraft.client.renderer.LightTexture;
+//import net.minecraft.client.resources.model.BakedModel;
+//import net.minecraft.util.Mth;
+//import net.minecraft.util.RandomSource;
+//import net.minecraft.world.entity.item.ItemEntity;
+//import net.minecraft.world.item.Item;
+//import net.minecraft.world.item.ItemDisplayContext;
+//import net.minecraft.world.item.ItemStack;
+//import net.minecraft.world.level.LightLayer;
+//
+//public class ItemVisual extends AbstractEntityVisual implements SimpleDynamicVisual {
+//
+// private static final ThreadLocal RANDOM = ThreadLocal.withInitial(RandomSource::createNewThreadLocalInstance);
+//
+// private final PoseStack pPoseStack = new PoseStack();
+// private BakedModel bakedModel;
+// private ItemStack currentStack;
+//
+// private InstanceRecycler instances;
+//
+// public ItemVisual(VisualizationContext ctx, ItemEntity entity, float partialTick) {
+// super(ctx, entity, partialTick);
+//
+// currentStack = entity.getItem();
+// bakedModel = ItemModels.getModel(currentStack);
+// var model = ItemModels.get(level, currentStack, ItemDisplayContext.GROUND);
+// instances = new InstanceRecycler<>(() -> ctx.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, model)
+// .createInstance());
+//
+// animate(partialTick);
+// }
+//
+// public static boolean isSupported(ItemEntity entity) {
+// return ItemModels.isSupported(entity.getItem());
+// }
+//
+// @Override
+// public void beginFrame(Context ctx) {
+// if (!isVisible(ctx.frustum())) {
+// return;
+// }
+//
+// animate(ctx.partialTick());
+// }
+//
+// private void animate(float partialTick) {
+// pPoseStack.setIdentity();
+// TransformStack.of(pPoseStack)
+// .translate(getVisualPosition(partialTick));
+//
+// ItemStack itemstack = entity.getItem();
+// if (!ItemStack.matches(itemstack, currentStack)) {
+// instances.delete();
+// currentStack = itemstack.copy();
+// bakedModel = ItemModels.getModel(currentStack);
+// var model = ItemModels.get(level, currentStack, ItemDisplayContext.GROUND);
+// instances = new InstanceRecycler<>(() -> visualizationContext.instancerProvider()
+// .instancer(InstanceTypes.TRANSFORMED, model)
+// .createInstance());
+// }
+// instances.resetCount();
+//
+// int i = itemstack.isEmpty() ? 187 : Item.getId(itemstack.getItem()) + itemstack.getDamageValue();
+// var random = RANDOM.get();
+// random.setSeed(i);
+// boolean flag = bakedModel.isGui3d();
+// int j = this.getRenderAmount(itemstack);
+// float f = 0.25F;
+// float f1 = shouldBob() ? Mth.sin(((float) entity.getAge() + partialTick) / 10.0F + entity.bobOffs) * 0.1F + 0.1F : 0;
+// float groundScaleX = bakedModel.getTransforms().ground.scale.y();
+// float groundScaleY = bakedModel.getTransforms().ground.scale.y();
+// float groundScaleZ = bakedModel.getTransforms().ground.scale.y();
+// pPoseStack.translate(0.0F, f1 + 0.25F * groundScaleZ, 0.0F);
+// float f3 = entity.getSpin(partialTick);
+// pPoseStack.mulPose(Axis.YP.rotation(f3));
+// if (!flag) {
+// float f7 = -0.0F * (float) (j - 1) * 0.5F * groundScaleX;
+// float f8 = -0.0F * (float) (j - 1) * 0.5F * groundScaleY;
+// float f9 = -0.09375F * (float) (j - 1) * 0.5F * groundScaleZ;
+// pPoseStack.translate(f7, f8, f9);
+// }
+//
+// int light = LightTexture.pack(level.getBrightness(LightLayer.BLOCK, entity.blockPosition()), level.getBrightness(LightLayer.SKY, entity.blockPosition()));
+//
+// for (int k = 0; k < j; ++k) {
+// pPoseStack.pushPose();
+// if (k > 0) {
+// if (flag) {
+// float f11 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F;
+// float f13 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F;
+// float f10 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F;
+// pPoseStack.translate(shouldSpreadItems() ? f11 : 0, shouldSpreadItems() ? f13 : 0, shouldSpreadItems() ? f10 : 0);
+// } else {
+// float f12 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F;
+// float f14 = (random.nextFloat() * 2.0F - 1.0F) * 0.15F * 0.5F;
+// pPoseStack.translate(shouldSpreadItems() ? f12 : 0, shouldSpreadItems() ? f14 : 0, 0.0D);
+// }
+// }
+//
+// instances.get()
+// .setTransform(pPoseStack.last())
+// .light(light)
+// .setChanged();
+// pPoseStack.popPose();
+// if (!flag) {
+// pPoseStack.translate(0.0, 0.0, 0.09375F * groundScaleZ);
+// }
+// }
+//
+// instances.discardExtra();
+// }
+//
+// protected int getRenderAmount(ItemStack pStack) {
+// int i = 1;
+// if (pStack.getCount() > 48) {
+// i = 5;
+// } else if (pStack.getCount() > 32) {
+// i = 4;
+// } else if (pStack.getCount() > 16) {
+// i = 3;
+// } else if (pStack.getCount() > 1) {
+// i = 2;
+// }
+//
+// return i;
+// }
+//
+// /**
+// * @return If items should spread out when rendered in 3D
+// */
+// public boolean shouldSpreadItems() {
+// return true;
+// }
+//
+// /**
+// * @return If items should have a bob effect
+// */
+// public boolean shouldBob() {
+// return true;
+// }
+//
+// @Override
+// protected void _delete() {
+// instances.delete();
+// }
+//
+//}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/MinecartVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/MinecartVisual.java
similarity index 69%
rename from common/src/vanillin/java/dev/engine_room/vanillin/visuals/MinecartVisual.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/MinecartVisual.java
index 1b495d6de..a1b833fd4 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/MinecartVisual.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/MinecartVisual.java
@@ -1,8 +1,8 @@
package dev.engine_room.vanillin.visuals;
-import org.jetbrains.annotations.Nullable;
import org.joml.Matrix4f;
import org.joml.Matrix4fStack;
+import org.jspecify.annotations.Nullable;
import dev.engine_room.flywheel.api.material.Material;
import dev.engine_room.flywheel.api.visual.DynamicVisual;
@@ -18,16 +18,22 @@
import dev.engine_room.flywheel.lib.visual.AbstractEntityVisual;
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import dev.engine_room.flywheel.lib.visual.SimpleTickableVisual;
+import dev.engine_room.vanillin.mixin.BlockModelSetAccessor;
+import net.minecraft.client.Minecraft;
import net.minecraft.client.model.geom.ModelLayerLocation;
-import net.minecraft.resources.ResourceLocation;
+import net.minecraft.client.renderer.block.BlockModelSet;
+import net.minecraft.resources.Identifier;
import net.minecraft.util.Mth;
-import net.minecraft.world.entity.vehicle.AbstractMinecart;
+import net.minecraft.world.entity.vehicle.minecart.AbstractMinecart;
+import net.minecraft.world.entity.vehicle.minecart.MinecartBehavior;
+import net.minecraft.world.entity.vehicle.minecart.NewMinecartBehavior;
+import net.minecraft.world.entity.vehicle.minecart.OldMinecartBehavior;
import net.minecraft.world.level.block.RenderShape;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.Vec3;
public class MinecartVisual extends AbstractEntityVisual implements SimpleTickableVisual, SimpleDynamicVisual {
- private static final ResourceLocation TEXTURE = ResourceLocation.withDefaultNamespace("textures/entity/minecart.png");
+ private static final Identifier TEXTURE = Identifier.withDefaultNamespace("textures/entity/minecart/minecart.png");
private static final Material MATERIAL = SimpleMaterial.builder()
.texture(TEXTURE)
.mipmap(false)
@@ -56,12 +62,12 @@ public MinecartVisual(VisualizationContext ctx, T entity, float partialTick, Mod
private TransformedInstance createContentsInstance() {
RenderShape shape = blockState.getRenderShape();
- if (shape == RenderShape.ENTITYBLOCK_ANIMATED) {
- instances.visible(false);
+ if (shape == RenderShape.INVISIBLE) {
return null;
}
- if (shape == RenderShape.INVISIBLE) {
+ if (hasSpecialRenderer(blockState)) {
+ instances.visible(false);
return null;
}
@@ -104,7 +110,6 @@ private void updateInstances(float partialTick) {
var renderOrigin = renderOrigin();
stack.translate((float) (posX - renderOrigin.getX()), (float) (posY - renderOrigin.getY()), (float) (posZ - renderOrigin.getZ()));
- float yaw = Mth.lerp(partialTick, entity.yRotO, entity.getYRot());
long randomBits = entity.getId() * 493286711L;
randomBits = randomBits * randomBits * 4392167121L + randomBits * 98761L;
@@ -113,33 +118,13 @@ private void updateInstances(float partialTick) {
float nudgeZ = (((float) (randomBits >> 24 & 7L) + 0.5f) / 8.0f - 0.5F) * 0.004f;
stack.translate(nudgeX, nudgeY, nudgeZ);
- Vec3 pos = entity.getPos(posX, posY, posZ);
- float pitch = Mth.lerp(partialTick, entity.xRotO, entity.getXRot());
- if (pos != null) {
- Vec3 offset1 = entity.getPosOffs(posX, posY, posZ, 0.3F);
- Vec3 offset2 = entity.getPosOffs(posX, posY, posZ, -0.3F);
-
- if (offset1 == null) {
- offset1 = pos;
- }
-
- if (offset2 == null) {
- offset2 = pos;
- }
-
- stack.translate((float) (pos.x - posX), (float) ((offset1.y + offset2.y) / 2.0D - posY), (float) (pos.z - posZ));
- Vec3 vec = offset2.add(-offset1.x, -offset1.y, -offset1.z);
- if (vec.length() != 0.0D) {
- vec = vec.normalize();
- yaw = (float) (Math.atan2(vec.z, vec.x) * 180.0D / Math.PI);
- pitch = (float) (Math.atan(vec.y) * 73.0D);
- }
+ MinecartBehavior behaviour = entity.getBehavior();
+ if (behaviour instanceof NewMinecartBehavior nmb) {
+ newRender(partialTick, nmb);
+ } else if (behaviour instanceof OldMinecartBehavior omb) {
+ oldRender(partialTick, omb, posX, posY, posZ);
}
- stack.translate(0.0F, 0.375F, 0.0F);
- stack.rotateY((180 - yaw) * Mth.DEG_TO_RAD);
- stack.rotateZ(-pitch * Mth.DEG_TO_RAD);
-
float hurtTime = entity.getHurtTime() - partialTick;
float damage = entity.getDamage() - partialTick;
@@ -168,6 +153,36 @@ private void updateInstances(float partialTick) {
updateLight(partialTick);
}
+ private void newRender(float partialTick, NewMinecartBehavior behavior) {
+ stack.rotateY(behavior.getCartLerpYRot(partialTick) * Mth.DEG_TO_RAD);
+ stack.rotateZ(-behavior.getCartLerpXRot(partialTick) * Mth.DEG_TO_RAD);
+ stack.translate(0.0F, 0.375F, 0.0F);
+ }
+
+ private void oldRender(float partialTick, OldMinecartBehavior behavior, double posX, double posY, double posZ) {
+ Vec3 pos = behavior.getPos(posX, posY, posZ);
+ float pitch = Mth.lerp(partialTick, entity.xRotO, entity.getXRot());
+ float yaw = Mth.lerp(partialTick, entity.yRotO, entity.getYRot());
+ if (pos != null) {
+ Vec3 frontPos = behavior.getPosOffs(posX, posY, posZ, 0.3F);
+ Vec3 backPos = behavior.getPosOffs(posX, posY, posZ, -0.3F);
+
+ if (frontPos != null && backPos != null) {
+ stack.translate((float) (pos.x - posX), (float) ((frontPos.y + backPos.y) / 2.0D - posY), (float) (pos.z - posZ));
+ Vec3 vec = backPos.add(-frontPos.x, -frontPos.y, -frontPos.z);
+ if (vec.length() != 0.0D) {
+ vec = vec.normalize();
+ yaw = (float) (Math.atan2(vec.z, vec.x) * 180.0D / Math.PI);
+ pitch = (float) (Math.atan(vec.y) * 73.0D);
+ }
+ }
+ }
+
+ stack.translate(0.0F, 0.375F, 0.0F);
+ stack.rotateY((180 - yaw) * Mth.DEG_TO_RAD);
+ stack.rotateZ(-pitch * Mth.DEG_TO_RAD);
+ }
+
protected void updateContents(TransformedInstance contents, Matrix4f pose, float partialTick) {
contents.setTransform(pose)
.setChanged();
@@ -191,6 +206,16 @@ protected void _delete() {
}
public static boolean shouldSkipRender(AbstractMinecart minecart) {
- return minecart.getDisplayBlockState().getRenderShape() != RenderShape.ENTITYBLOCK_ANIMATED;
+ BlockState state = minecart.getDisplayBlockState();
+ if (state.getRenderShape() == RenderShape.INVISIBLE) {
+ return true;
+ } else {
+ return !hasSpecialRenderer(state);
+ }
+ }
+
+ private static boolean hasSpecialRenderer(BlockState state) {
+ BlockModelSet blockModelSet = Minecraft.getInstance().getModelManager().getBlockModelSet();
+ return ((BlockModelSetAccessor) blockModelSet).flywheel$getBlockModelByStateCache().containsKey(state);
}
}
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java
similarity index 97%
rename from common/src/vanillin/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java
index 0080041a1..a957982a3 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/ShulkerBoxVisual.java
@@ -16,6 +16,7 @@
import dev.engine_room.flywheel.lib.visual.SimpleDynamicVisual;
import net.minecraft.client.model.geom.ModelLayers;
import net.minecraft.client.renderer.Sheets;
+import net.minecraft.client.resources.model.sprite.SpriteId;
import net.minecraft.core.Direction;
import net.minecraft.util.Mth;
import net.minecraft.world.item.DyeColor;
@@ -42,7 +43,7 @@ public ShulkerBoxVisual(VisualizationContext ctx, ShulkerBoxBlockEntity blockEnt
super(ctx, blockEntity, partialTick);
DyeColor color = blockEntity.getColor();
- net.minecraft.client.resources.model.Material texture;
+ SpriteId texture;
if (color == null) {
texture = Sheets.DEFAULT_SHULKER_TEXTURE_LOCATION;
} else {
diff --git a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java
similarity index 95%
rename from common/src/vanillin/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java
rename to vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java
index 7cf6d0736..b21f04caf 100644
--- a/common/src/vanillin/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java
+++ b/vanillin/common/src/main/java/dev/engine_room/vanillin/visuals/TntMinecartVisual.java
@@ -7,7 +7,7 @@
import net.minecraft.client.model.geom.ModelLayers;
import net.minecraft.client.renderer.texture.OverlayTexture;
import net.minecraft.util.Mth;
-import net.minecraft.world.entity.vehicle.MinecartTNT;
+import net.minecraft.world.entity.vehicle.minecart.MinecartTNT;
public class TntMinecartVisual extends MinecartVisual {
private static final int WHITE_OVERLAY = OverlayTexture.pack(OverlayTexture.u(1.0F), 10);
diff --git a/common/src/vanillin/resources/assets/vanillin/flywheel/instance/cull/glyph.glsl b/vanillin/common/src/main/resources/assets/vanillin/flywheel/instance/cull/glyph.glsl
similarity index 100%
rename from common/src/vanillin/resources/assets/vanillin/flywheel/instance/cull/glyph.glsl
rename to vanillin/common/src/main/resources/assets/vanillin/flywheel/instance/cull/glyph.glsl
diff --git a/common/src/vanillin/resources/assets/vanillin/flywheel/instance/glyph.vert b/vanillin/common/src/main/resources/assets/vanillin/flywheel/instance/glyph.vert
similarity index 100%
rename from common/src/vanillin/resources/assets/vanillin/flywheel/instance/glyph.vert
rename to vanillin/common/src/main/resources/assets/vanillin/flywheel/instance/glyph.vert
diff --git a/common/src/vanillin/resources/logo.png b/vanillin/common/src/main/resources/logo.png
similarity index 100%
rename from common/src/vanillin/resources/logo.png
rename to vanillin/common/src/main/resources/logo.png
diff --git a/vanillin/common/src/main/resources/vanillin.mixins.json b/vanillin/common/src/main/resources/vanillin.mixins.json
new file mode 100644
index 000000000..f98a953ba
--- /dev/null
+++ b/vanillin/common/src/main/resources/vanillin.mixins.json
@@ -0,0 +1,13 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "dev.engine_room.vanillin.mixin",
+ "compatibilityLevel": "JAVA_25",
+ "client": [
+ "BlockModelSetAccessor",
+ "ChestRendererAccessor"
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/vanillin/fabric/build.gradle.kts b/vanillin/fabric/build.gradle.kts
new file mode 100644
index 000000000..a6c30f0c4
--- /dev/null
+++ b/vanillin/fabric/build.gradle.kts
@@ -0,0 +1,37 @@
+plugins {
+ alias(libs.plugins.flywheel.gradle)
+ alias(libs.plugins.configure.base)
+ alias(libs.plugins.configure.fabric)
+ alias(libs.plugins.setup.repositories)
+}
+
+val vanillinCommon = projects.vanillin.vanillinCommon.path
+val platform = projects.flywheelFabric.path
+
+val main = sourceSets.getByName("main")
+
+transitiveSourceSets {
+ sourceSet(main) {
+ compileClasspath(project(platform), "api", "lib", "main")
+
+ bundleFrom(project(vanillinCommon))
+ }
+}
+
+defaultPackageInfos {
+ sources(main)
+}
+
+dependencies {
+ implementation(libs.fabric.loader)
+ api(libs.fabric.api)
+
+ compileOnly(libs.sodium.fabric.api)
+
+ compileOnly(project(path = vanillinCommon, configuration = "mainClasses"))
+ compileOnly(project(path = vanillinCommon, configuration = "mainResources"))
+
+ compileOnly(project(path = platform, configuration = "apiClasses"))
+
+ include(runtimeOnly(project(path = platform, configuration = "flywheel"))!!)
+}
diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/FabricVanillinConfig.java b/vanillin/fabric/src/main/java/dev/engine_room/vanillin/FabricVanillinConfig.java
similarity index 100%
rename from vanillinFabric/src/main/java/dev/engine_room/vanillin/FabricVanillinConfig.java
rename to vanillin/fabric/src/main/java/dev/engine_room/vanillin/FabricVanillinConfig.java
diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java b/vanillin/fabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java
similarity index 78%
rename from vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java
rename to vanillin/fabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java
index ca9ffca6d..339f04ced 100644
--- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java
+++ b/vanillin/fabric/src/main/java/dev/engine_room/vanillin/VanillinFabric.java
@@ -3,7 +3,7 @@
import dev.engine_room.flywheel.api.event.ReloadLevelRendererCallback;
import dev.engine_room.vanillin.item.SodiumAnimatedTextureCompat;
import net.fabricmc.api.ClientModInitializer;
-import net.fabricmc.fabric.api.client.rendering.v1.WorldRenderEvents;
+import net.fabricmc.fabric.api.client.rendering.v1.level.LevelRenderEvents;
public class VanillinFabric implements ClientModInitializer {
@Override
@@ -14,6 +14,6 @@ public void onInitializeClient() {
FabricVanillinConfig.INSTANCE.save();
ReloadLevelRendererCallback.EVENT.register(level -> SodiumAnimatedTextureCompat.onReloadRenderer());
- WorldRenderEvents.START.register(context -> SodiumAnimatedTextureCompat.beginFrame());
+ LevelRenderEvents.START_MAIN.register(context -> SodiumAnimatedTextureCompat.beginFrame());
}
}
diff --git a/vanillin/fabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java b/vanillin/fabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java
new file mode 100644
index 000000000..c6608f247
--- /dev/null
+++ b/vanillin/fabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java
@@ -0,0 +1,17 @@
+package dev.engine_room.vanillin;
+
+import net.fabricmc.loader.api.FabricLoader;
+
+public class VanillinXplatImpl implements VanillinXplat {
+ @Override
+ public boolean isDevelopmentEnvironment() {
+ return FabricLoader.getInstance()
+ .isDevelopmentEnvironment();
+ }
+
+ @Override
+ public boolean isModLoaded(String modId) {
+ return FabricLoader.getInstance()
+ .isModLoaded(modId);
+ }
+}
diff --git a/vanillin/fabric/src/main/resources/fabric.mod.json b/vanillin/fabric/src/main/resources/fabric.mod.json
new file mode 100644
index 000000000..25c9a0db0
--- /dev/null
+++ b/vanillin/fabric/src/main/resources/fabric.mod.json
@@ -0,0 +1,34 @@
+{
+ "schemaVersion": 1,
+ "id": "${mod_id}",
+ "name": "${mod_name}",
+ "version": "${mod_version}",
+ "description": "${mod_description}",
+ "authors": [
+ "${mod_authors_json}"
+ ],
+ "contact": {
+ "homepage": "${mod_homepage}",
+ "sources": "${mod_sources}",
+ "issues": "${mod_issues}"
+ },
+ "license": "${mod_license}",
+ "icon": "logo.png",
+ "environment": "client",
+ "entrypoints": {
+ "client": [
+ "dev.engine_room.vanillin.VanillinFabric"
+ ]
+ },
+ "mixins": [
+ "vanillin.mixins.json",
+ "vanillin.fabric.mixins.json"
+ ],
+ "depends": {
+ "minecraft": "${minecraft_version}",
+ "fabricloader": ">=${fabric_loader_version}",
+ "fabric-api": ">=${fabric_api_version}",
+ "flywheel": "${flywheel_semver_version_range}",
+ "java": ">=${java_version}"
+ }
+}
diff --git a/vanillin/fabric/src/main/resources/vanillin.fabric.mixins.json b/vanillin/fabric/src/main/resources/vanillin.fabric.mixins.json
new file mode 100644
index 000000000..2d485d46d
--- /dev/null
+++ b/vanillin/fabric/src/main/resources/vanillin.fabric.mixins.json
@@ -0,0 +1,11 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "dev.engine_room.vanillin.fabric.mixin",
+ "compatibilityLevel": "JAVA_25",
+ "client": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/vanillin/neoforge/build.gradle.kts b/vanillin/neoforge/build.gradle.kts
new file mode 100644
index 000000000..18f0a4f7b
--- /dev/null
+++ b/vanillin/neoforge/build.gradle.kts
@@ -0,0 +1,34 @@
+plugins {
+ alias(libs.plugins.flywheel.gradle)
+ alias(libs.plugins.configure.base)
+ alias(libs.plugins.configure.neoforge)
+ alias(libs.plugins.setup.repositories)
+}
+
+val vanillinCommon = projects.vanillin.vanillinCommon.path
+val platform = projects.flywheelNeoforge.path
+
+val main = sourceSets.getByName("main")
+
+transitiveSourceSets {
+ sourceSet(main) {
+ compileClasspath(project(platform), "api", "lib", "main")
+
+ bundleFrom(project(vanillinCommon))
+ }
+}
+
+defaultPackageInfos {
+ sources(main)
+}
+
+dependencies {
+ compileOnly(libs.sodium.neoforge.api)
+
+ compileOnly(project(path = vanillinCommon, configuration = "mainClasses"))
+ compileOnly(project(path = vanillinCommon, configuration = "mainResources"))
+
+ compileOnly(project(path = platform, configuration = "apiClasses"))
+
+ jarJar(runtimeOnly(project(path = platform, configuration = "flywheel"))!!)
+}
diff --git a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/NeoForgeVanillinConfig.java b/vanillin/neoforge/src/main/java/dev/engine_room/vanillin/NeoForgeVanillinConfig.java
similarity index 100%
rename from vanillinNeoForge/src/main/java/dev/engine_room/vanillin/NeoForgeVanillinConfig.java
rename to vanillin/neoforge/src/main/java/dev/engine_room/vanillin/NeoForgeVanillinConfig.java
diff --git a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinNeoForgeClient.java b/vanillin/neoforge/src/main/java/dev/engine_room/vanillin/VanillinNeoForgeClient.java
similarity index 100%
rename from vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinNeoForgeClient.java
rename to vanillin/neoforge/src/main/java/dev/engine_room/vanillin/VanillinNeoForgeClient.java
diff --git a/vanillin/neoforge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java b/vanillin/neoforge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java
new file mode 100644
index 000000000..415bc64d6
--- /dev/null
+++ b/vanillin/neoforge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java
@@ -0,0 +1,15 @@
+package dev.engine_room.vanillin;
+
+import net.neoforged.fml.loading.FMLLoader;
+
+public class VanillinXplatImpl implements VanillinXplat {
+ @Override
+ public boolean isDevelopmentEnvironment() {
+ return !FMLLoader.getCurrent().isProduction();
+ }
+
+ @Override
+ public boolean isModLoaded(String modId) {
+ return FMLLoader.getCurrent().getLoadingModList().getModFileById(modId) != null;
+ }
+}
diff --git a/vanillinNeoForge/src/main/resources/META-INF/neoforge.mods.toml b/vanillin/neoforge/src/main/resources/META-INF/neoforge.mods.toml
similarity index 50%
rename from vanillinNeoForge/src/main/resources/META-INF/neoforge.mods.toml
rename to vanillin/neoforge/src/main/resources/META-INF/neoforge.mods.toml
index 5d84a3a46..17cce6ccd 100644
--- a/vanillinNeoForge/src/main/resources/META-INF/neoforge.mods.toml
+++ b/vanillin/neoforge/src/main/resources/META-INF/neoforge.mods.toml
@@ -1,16 +1,16 @@
modLoader = "javafml"
-# The loader version doesn't matter. Modify the Forge and/or Minecraft version ranges instead.
+# The loader version doesn't matter. Modify the NeoForge and/or Minecraft version ranges instead.
loaderVersion = "[0,)"
license = "${mod_license}"
issueTrackerURL = "${mod_issues}"
[[mods]]
-modId = "${vanillin_id}"
-version = "${vanillin_version}"
-displayName = "${vanillin_name}"
-description = "${vanillin_description}"
+modId = "${mod_id}"
+version = "${mod_version}"
+displayName = "${mod_name}"
+description = "${mod_description}"
logoFile = "logo.png"
-authors = "Jozufozu, PepperCode1"
+authors = "${mod_authors}"
displayURL = "${mod_homepage}"
displayTest = "IGNORE_ALL_VERSION"
@@ -19,20 +19,20 @@ config = "vanillin.mixins.json"
[[mixins]]
config = "vanillin.neoforge.mixins.json"
-[[dependencies.${ vanillin_id }]]
+[[dependencies."${mod_id}"]]
modId = "minecraft"
type = "required"
-versionRange = "${minecraft_maven_version_range}"
+versionRange = "[${minecraft_version}]"
side = "CLIENT"
-[[dependencies.${ vanillin_id }]]
+[[dependencies."${mod_id}"]]
modId = "neoforge"
type = "required"
-versionRange = "${neoforge_version_range}"
+versionRange = "[${neoforge_version},)"
side = "CLIENT"
-[[dependencies.${ vanillin_id }]]
-modId = "${flywheel_id}"
+[[dependencies."${mod_id}"]]
+modId = "flywheel"
type = "required"
versionRange = "${flywheel_maven_version_range}"
side = "CLIENT"
diff --git a/vanillin/neoforge/src/main/resources/vanillin.neoforge.mixins.json b/vanillin/neoforge/src/main/resources/vanillin.neoforge.mixins.json
new file mode 100644
index 000000000..25cc5ec7b
--- /dev/null
+++ b/vanillin/neoforge/src/main/resources/vanillin.neoforge.mixins.json
@@ -0,0 +1,11 @@
+{
+ "required": true,
+ "minVersion": "0.8",
+ "package": "dev.engine_room.vanillin.neoforge.mixin",
+ "compatibilityLevel": "JAVA_25",
+ "client": [
+ ],
+ "injectors": {
+ "defaultRequire": 1
+ }
+}
diff --git a/vanillinFabric/build.gradle.kts b/vanillinFabric/build.gradle.kts
deleted file mode 100644
index 324865e0e..000000000
--- a/vanillinFabric/build.gradle.kts
+++ /dev/null
@@ -1,89 +0,0 @@
-plugins {
- idea
- java
- `maven-publish`
- id("dev.architectury.loom")
- id("flywheel.subproject")
- id("flywheel.platform")
-}
-
-val common = ":common"
-val platform = ":fabric"
-
-subproject.init("vanillin-fabric", "vanillin_group", "vanillin_version")
-
-val main = sourceSets.getByName("main")
-
-platform {
- setupLoomRuns()
-}
-
-transitiveSourceSets {
- sourceSet(main) {
- compileClasspath(project(platform), "api", "lib", "main")
-
- bundleFrom(project(common), "vanillin")
- }
-}
-
-var vanillinVersion = "${property("vanillin_version")}+${property("minecraft_version")}"
-
-if (subproject.buildNumber != null) {
- vanillinVersion += ".build.${subproject.buildNumber}"
-}
-
-val replaceProperties = listOf(
- "mod_license",
- "mod_sources",
- "mod_issues",
- "mod_homepage",
- "flywheel_id",
- "vanillin_id",
- "vanillin_name",
- "vanillin_description",
- "minecraft_semver_version_range",
- "flywheel_semver_version_range",
- "fabric_api_version_range",
-).associateWith { property(it) as String }
- .plus("vanillin_version" to vanillinVersion)
-
-tasks.withType().configureEach {
- inputs.properties(replaceProperties)
-
- filesMatching(listOf("fabric.mod.json")) {
- expand(replaceProperties)
- }
-}
-
-jarSets {
- mainSet.publishWithRemappedSources {
- artifactId = "vanillin-fabric-${property("artifact_minecraft_version")}"
- }
-}
-
-defaultPackageInfos {
- sources(main)
-}
-
-loom {
- mixin {
- useLegacyMixinAp = true
- add(main, "vanillin.refmap.json")
- }
-}
-
-dependencies {
- modImplementation("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
- modApi("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}")
-
- modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric")
-
- compileOnly(project(path = common, configuration = "vanillinClasses"))
- compileOnly(project(path = common, configuration = "vanillinResources"))
-
- compileOnly(project(path = platform, configuration = "apiClasses"))
-
- // JiJ flywheel proper
- include(project(path = platform, configuration = "flywheelRemap"))
- runtimeOnly(project(path = platform, configuration = "flywheelDev"))
-}
diff --git a/vanillinFabric/gradle.properties b/vanillinFabric/gradle.properties
deleted file mode 100644
index e846a8f57..000000000
--- a/vanillinFabric/gradle.properties
+++ /dev/null
@@ -1 +0,0 @@
-loom.platform=fabric
diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java
deleted file mode 100644
index df1cf7db7..000000000
--- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package dev.engine_room.vanillin;
-
-import org.jetbrains.annotations.Nullable;
-
-import dev.engine_room.vanillin.fabric.mixin.item.ItemColorsAccessor;
-import dev.engine_room.vanillin.fabric.mixin.item.MinecraftAccessor;
-import net.fabricmc.loader.api.FabricLoader;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.color.item.ItemColor;
-import net.minecraft.core.registries.BuiltInRegistries;
-import net.minecraft.world.item.Item;
-
-public class VanillinXplatImpl implements VanillinXplat {
- @Override
- public boolean isDevelopmentEnvironment() {
- return FabricLoader.getInstance()
- .isDevelopmentEnvironment();
- }
-
- @Override
- @Nullable
- public ItemColor itemColors(Item item) {
- var itemColors = ((ItemColorsAccessor) ((MinecraftAccessor) Minecraft.getInstance()).vanillin$itemColors()).vanillin$itemColors();
- return itemColors.byId(BuiltInRegistries.ITEM.getId(item));
- }
-
- @Override
- public boolean isModLoaded(String modId) {
- return FabricLoader.getInstance()
- .isModLoaded(modId);
- }
-}
diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/ItemColorsAccessor.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/ItemColorsAccessor.java
deleted file mode 100644
index 78b2e5559..000000000
--- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/ItemColorsAccessor.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package dev.engine_room.vanillin.fabric.mixin.item;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.gen.Accessor;
-
-import net.minecraft.client.color.item.ItemColor;
-import net.minecraft.client.color.item.ItemColors;
-import net.minecraft.core.IdMapper;
-
-@Mixin(ItemColors.class)
-public interface ItemColorsAccessor {
- @Accessor("itemColors")
- IdMapper vanillin$itemColors();
-}
diff --git a/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/MinecraftAccessor.java b/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/MinecraftAccessor.java
deleted file mode 100644
index 3347ecb9e..000000000
--- a/vanillinFabric/src/main/java/dev/engine_room/vanillin/fabric/mixin/item/MinecraftAccessor.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package dev.engine_room.vanillin.fabric.mixin.item;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.gen.Accessor;
-
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.color.item.ItemColors;
-
-@Mixin(Minecraft.class)
-public interface MinecraftAccessor {
- @Accessor("itemColors")
- ItemColors vanillin$itemColors();
-}
diff --git a/vanillinFabric/src/main/resources/fabric.mod.json b/vanillinFabric/src/main/resources/fabric.mod.json
deleted file mode 100644
index b574b1eac..000000000
--- a/vanillinFabric/src/main/resources/fabric.mod.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "schemaVersion" : 1,
- "id" : "${vanillin_id}",
- "version" : "${vanillin_version}",
- "name" : "${vanillin_name}",
- "description" : "${vanillin_description}",
- "authors" : [
- "Jozufozu",
- "PepperCode1"
- ],
- "contact" : {
- "homepage" : "${mod_homepage}",
- "sources" : "${mod_sources}",
- "issues" : "${mod_issues}"
- },
- "license" : "${mod_license}",
- "icon" : "logo.png",
- "environment" : "client",
- "entrypoints" : {
- "client" : [
- "dev.engine_room.vanillin.VanillinFabric"
- ]
- },
- "mixins" : [
- "vanillin.mixins.json",
- "vanillin.fabric.mixins.json"
- ],
- "depends" : {
- "minecraft" : "${minecraft_semver_version_range}",
- "fabricloader" : ">=0.15.0",
- "fabric-api" : "${fabric_api_version_range}",
- "${flywheel_id}" : "${flywheel_semver_version_range}"
- },
- "breaks" : {
- }
-}
diff --git a/vanillinFabric/src/main/resources/vanillin.fabric.mixins.json b/vanillinFabric/src/main/resources/vanillin.fabric.mixins.json
deleted file mode 100644
index 88c9e26b6..000000000
--- a/vanillinFabric/src/main/resources/vanillin.fabric.mixins.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "required" : true,
- "minVersion" : "0.8",
- "package" : "dev.engine_room.vanillin.fabric.mixin",
- "compatibilityLevel" : "JAVA_17",
- "refmap" : "vanillin.refmap.json",
- "client" : [
- "item.ItemColorsAccessor",
- "item.MinecraftAccessor"
- ],
- "injectors" : {
- "defaultRequire" : 1
- }
-}
diff --git a/vanillinNeoForge/build.gradle.kts b/vanillinNeoForge/build.gradle.kts
deleted file mode 100644
index 4ee406606..000000000
--- a/vanillinNeoForge/build.gradle.kts
+++ /dev/null
@@ -1,98 +0,0 @@
-plugins {
- idea
- java
- `maven-publish`
- id("dev.architectury.loom")
- id("flywheel.subproject")
- id("flywheel.platform")
-}
-
-val common = ":common"
-val platform = ":neoforge"
-
-subproject.init("vanillin-neoforge", "vanillin_group", "vanillin_version")
-
-val main = sourceSets.getByName("main")
-
-platform {
- setupLoomRuns()
-}
-
-transitiveSourceSets {
- sourceSet(main) {
- compileClasspath(project(platform), "api", "lib", "main")
-
- bundleFrom(project(common), "vanillin")
- }
-}
-
-val replaceProperties = listOf(
- "mod_license",
- "mod_sources",
- "mod_issues",
- "mod_homepage",
- "flywheel_id",
- "vanillin_id",
- "vanillin_name",
- "vanillin_description",
- "flywheel_maven_version_range",
- "minecraft_maven_version_range",
- "neoforge_version_range",
-).associateWith { property(it) as String }
- .plus("vanillin_version" to "${property("vanillin_version")}${if (subproject.buildNumber != null) "-${subproject.buildNumber}" else ""}")
-
-tasks.withType().configureEach {
- inputs.properties(replaceProperties)
-
- filesMatching(listOf("pack.mcmeta", "META-INF/neoforge.mods.toml")) {
- expand(replaceProperties)
- }
-}
-
-jarSets {
- mainSet.publishWithRawSources {
- artifactId = "vanillin-neoforge-${property("artifact_minecraft_version")}"
- }
-}
-
-defaultPackageInfos {
- sources(main)
-}
-
-loom {
- mixin {
- useLegacyMixinAp = true
- add(main, "vanillin.refmap.json")
- }
-
- runs {
- configureEach {
- property("forge.logging.markers", "")
- property("forge.logging.console.level", "debug")
- }
- }
-}
-
-repositories {
- maven("https://maven.neoforged.net/releases/")
-}
-
-dependencies {
- neoForge("net.neoforged:neoforge:${property("neoforge_version")}")
-
- modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-neoforge")
- modCompileOnly("maven.modrinth:iris:${property("iris_version")}-neoforge")
-
- modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}")
-
- compileOnly(project(path = common, configuration = "vanillinClasses"))
- compileOnly(project(path = common, configuration = "vanillinResources"))
-
- compileOnly(project(path = platform, configuration = "apiClasses"))
-
- compileOnly(annotationProcessor("io.github.llamalad7:mixinextras-common:0.4.1")!!)
-
- // JiJ flywheel proper
- include(project(path = platform, configuration = "flywheelRemap"))
- runtimeOnly(project(path = platform, configuration = "flywheelDev"))
-}
diff --git a/vanillinNeoForge/gradle.properties b/vanillinNeoForge/gradle.properties
deleted file mode 100644
index 2e6ed7676..000000000
--- a/vanillinNeoForge/gradle.properties
+++ /dev/null
@@ -1 +0,0 @@
-loom.platform = neoforge
diff --git a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java b/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java
deleted file mode 100644
index 3ad095ebb..000000000
--- a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/VanillinXplatImpl.java
+++ /dev/null
@@ -1,28 +0,0 @@
-package dev.engine_room.vanillin;
-
-import dev.engine_room.vanillin.neoforge.mixin.item.ItemColorsAccessor;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.color.item.ItemColor;
-import net.minecraft.world.item.Item;
-import net.neoforged.fml.loading.FMLEnvironment;
-import net.neoforged.fml.loading.LoadingModList;
-
-public class VanillinXplatImpl implements VanillinXplat {
- @Override
- public boolean isDevelopmentEnvironment() {
- return !FMLEnvironment.production;
- }
-
- @Override
- public ItemColor itemColors(Item item) {
- return ((ItemColorsAccessor) Minecraft.getInstance()
- .getItemColors()).vanillin$itemColors()
- .get(item);
- }
-
- @Override
- public boolean isModLoaded(String modId) {
- return LoadingModList.get()
- .getModFileById(modId) != null;
- }
-}
diff --git a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/neoforge/mixin/item/ItemColorsAccessor.java b/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/neoforge/mixin/item/ItemColorsAccessor.java
deleted file mode 100644
index 3f161386e..000000000
--- a/vanillinNeoForge/src/main/java/dev/engine_room/vanillin/neoforge/mixin/item/ItemColorsAccessor.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package dev.engine_room.vanillin.neoforge.mixin.item;
-
-import java.util.Map;
-
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.gen.Accessor;
-
-import net.minecraft.client.color.item.ItemColor;
-import net.minecraft.client.color.item.ItemColors;
-import net.minecraft.world.item.Item;
-
-@Mixin(ItemColors.class)
-public interface ItemColorsAccessor {
- @Accessor("itemColors")
- Map
- vanillin$itemColors();
-}
diff --git a/vanillinNeoForge/src/main/resources/pack.mcmeta b/vanillinNeoForge/src/main/resources/pack.mcmeta
deleted file mode 100644
index 0d29ea3f1..000000000
--- a/vanillinNeoForge/src/main/resources/pack.mcmeta
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "pack": {
- "description": "${vanillin_name} resources",
- "pack_format": 15
- }
-}
diff --git a/vanillinNeoForge/src/main/resources/vanillin.neoforge.mixins.json b/vanillinNeoForge/src/main/resources/vanillin.neoforge.mixins.json
deleted file mode 100644
index f4941242a..000000000
--- a/vanillinNeoForge/src/main/resources/vanillin.neoforge.mixins.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "required" : true,
- "minVersion" : "0.8",
- "package" : "dev.engine_room.vanillin.neoforge.mixin",
- "compatibilityLevel" : "JAVA_17",
- "refmap" : "vanillin.refmap.json",
- "client" : [
- "item.ItemColorsAccessor"
- ],
- "injectors" : {
- "defaultRequire" : 1
- }
-}