errorConsumer = error -> {};
private CompilationFactory factory = Compilation::new;
private Includer includer = RecursiveIncluder.INSTANCE;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java
index 6ec625409..8b43f4d82 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java
@@ -2,14 +2,12 @@ package com.jozufozu.flywheel.backend.engine;
import java.util.ArrayList;
import java.util.BitSet;
-import java.util.List;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.instancer.Instancer;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
public abstract class AbstractInstancer implements Instancer
{
-
public final StructType
type;
// Lock for all instance data, only needs to be used in methods that may run on the TaskExecutor.
@@ -42,30 +40,33 @@ public abstract class AbstractInstancer
implements Insta
}
}
- /**
- * Clear all instance data without freeing resources.
- */
- public void clear() {
- handles.forEach(HandleImpl::clear);
- data.clear();
- handles.clear();
- changed.clear();
- deleted.clear();
- }
-
public int getInstanceCount() {
return data.size();
}
- public List
getRange(int start, int end) {
- return data.subList(start, end);
+ public void notifyDirty(int index) {
+ if (index < 0 || index >= getInstanceCount()) {
+ return;
+ }
+ synchronized (lock) {
+ changed.set(index);
+ }
}
- public List
getAll() {
- return data;
+ public void notifyRemoval(int index) {
+ if (index < 0 || index >= getInstanceCount()) {
+ return;
+ }
+ synchronized (lock) {
+ deleted.set(index);
+ }
}
protected void removeDeletedInstances() {
+ if (deleted.isEmpty()) {
+ return;
+ }
+
// Figure out which elements are to be removed.
final int oldSize = this.data.size();
int removeCount = deleted.cardinality();
@@ -95,26 +96,19 @@ public abstract class AbstractInstancer
implements Insta
.clear();
}
+ /**
+ * Clear all instance data without freeing resources.
+ */
+ public void clear() {
+ handles.forEach(HandleImpl::clear);
+ data.clear();
+ handles.clear();
+ changed.clear();
+ deleted.clear();
+ }
+
@Override
public String toString() {
- return "Instancer[" + getInstanceCount() + ']';
- }
-
- public void notifyDirty(int index) {
- if (index < 0 || index >= getInstanceCount()) {
- return;
- }
- synchronized (lock) {
- changed.set(index);
- }
- }
-
- public void notifyRemoval(int index) {
- if (index < 0 || index >= getInstanceCount()) {
- return;
- }
- synchronized (lock) {
- deleted.set(index);
- }
+ return "AbstractInstancer[" + getInstanceCount() + ']';
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/HandleImpl.java b/src/main/java/com/jozufozu/flywheel/backend/engine/HandleImpl.java
index 915ef8249..28ebebcda 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/HandleImpl.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/HandleImpl.java
@@ -1,9 +1,8 @@
package com.jozufozu.flywheel.backend.engine;
-import com.jozufozu.flywheel.api.instancer.Handle;
+import com.jozufozu.flywheel.api.struct.Handle;
public class HandleImpl implements Handle {
-
private final AbstractInstancer> instancer;
private int index;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java
index 39fa9840a..3cbf4458a 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java
@@ -1,8 +1,8 @@
package com.jozufozu.flywheel.backend.engine;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.model.Model;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
public record InstancerKey
(StructType
type, Model model, RenderStage stage) {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/UniformBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/UniformBuffer.java
index 747bfcfd9..ee7497703 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/UniformBuffer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/UniformBuffer.java
@@ -10,9 +10,9 @@ import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
import com.jozufozu.flywheel.gl.buffer.GlBuffer;
import com.jozufozu.flywheel.gl.buffer.GlBufferType;
import com.jozufozu.flywheel.gl.shader.GlProgram;
+import com.jozufozu.flywheel.lib.math.MoreMath;
+import com.jozufozu.flywheel.lib.math.RenderMath;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
-import com.jozufozu.flywheel.util.FlwUtil;
-import com.jozufozu.flywheel.util.RenderMath;
public class UniformBuffer {
@@ -93,7 +93,7 @@ public class UniformBuffer {
var builder = ImmutableList.builder();
int totalBytes = 0;
for (ShaderUniforms provider : providers) {
- int size = FlwUtil.align16(provider.byteSize());
+ int size = MoreMath.align16(provider.byteSize());
builder.add(new LiveProvider(provider, totalBytes, size));
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedMeshPool.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedMeshPool.java
index 5bddbf1af..1dde158b4 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedMeshPool.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchedMeshPool.java
@@ -39,6 +39,10 @@ public class BatchedMeshPool {
growthMargin = vertexFormat.getVertexSize() * 32;
}
+ public VertexFormat getVertexFormat() {
+ return vertexFormat;
+ }
+
/**
* Allocate a mesh in the arena.
*
@@ -139,10 +143,6 @@ public class BatchedMeshPool {
pendingUpload.clear();
}
- public VertexFormat getVertexFormat() {
- return vertexFormat;
- }
-
@Override
public String toString() {
return "BatchedMeshPool{" + "vertexFormat=" + vertexFormat + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java
index 3e62c61ff..fc5a58870 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java
@@ -5,9 +5,9 @@ import java.util.List;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.model.Model;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.task.TaskExecutor;
import com.jozufozu.flywheel.util.FlwUtil;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingTransformManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingTransformManager.java
index b07d78952..214a6c2c4 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingTransformManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingTransformManager.java
@@ -15,10 +15,10 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.model.Mesh;
import com.jozufozu.flywheel.api.model.Model;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.engine.InstancerKey;
import com.mojang.blaze3d.vertex.VertexFormat;
@@ -83,7 +83,7 @@ public class BatchingTransformManager {
var meshes = model.getMeshes();
for (var entry : meshes.entrySet()) {
var material = entry.getKey();
- var renderType = material.getBatchingRenderType();
+ RenderType renderType = material.getBatchingRenderType();
TransformCall> transformCall = new TransformCall<>(instancer, material, alloc(entry.getValue(), renderType.format()));
transformSet.put(renderType, transformCall);
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/CPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/CPUInstancer.java
index 99306a267..6ac7aad78 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/CPUInstancer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/CPUInstancer.java
@@ -1,18 +1,25 @@
package com.jozufozu.flywheel.backend.engine.batching;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
+import java.util.List;
+
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
public class CPUInstancer extends AbstractInstancer
{
-
public CPUInstancer(StructType
type) {
super(type);
}
- void update() {
- if (!deleted.isEmpty()) {
- removeDeletedInstances();
- }
+ public List
getRange(int start, int end) {
+ return data.subList(start, end);
+ }
+
+ public List
getAll() {
+ return data;
+ }
+
+ public void update() {
+ removeDeletedInstances();
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/DrawBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/DrawBuffer.java
index aabe7de76..7d5318750 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/DrawBuffer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/DrawBuffer.java
@@ -32,7 +32,7 @@ public class DrawBuffer {
private boolean prepared;
private int vertexCount;
- DrawBuffer(RenderType renderType, VertexFormat format, int stride, VertexListProvider provider) {
+ public DrawBuffer(RenderType renderType, VertexFormat format, int stride, VertexListProvider provider) {
this.renderType = renderType;
this.format = format;
this.stride = stride;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/DrawBufferSet.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/DrawBufferSet.java
index c4c15093f..884435ab8 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/DrawBufferSet.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/DrawBufferSet.java
@@ -3,8 +3,6 @@ package com.jozufozu.flywheel.backend.engine.batching;
import java.util.EnumMap;
import java.util.Map;
-import org.jetbrains.annotations.ApiStatus;
-
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
import com.jozufozu.flywheel.api.vertex.VertexListProviderRegistry;
@@ -20,7 +18,6 @@ public class DrawBufferSet {
private final Map buffers = new EnumMap<>(RenderStage.class);
- @ApiStatus.Internal
public DrawBufferSet(RenderType renderType) {
this.renderType = renderType;
format = renderType.format();
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/TransformCall.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/TransformCall.java
index 003337564..61f1c61ba 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/TransformCall.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/TransformCall.java
@@ -2,17 +2,16 @@ package com.jozufozu.flywheel.backend.engine.batching;
import java.util.List;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.material.Material;
-import com.jozufozu.flywheel.api.struct.StructType;
+import com.jozufozu.flywheel.api.struct.InstancePart;
+import com.jozufozu.flywheel.api.struct.StructVertexTransformer;
import com.jozufozu.flywheel.api.task.TaskExecutor;
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
+import com.jozufozu.flywheel.lib.vertex.VertexTransformations;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
-import com.mojang.math.Vector3f;
-import com.mojang.math.Vector4f;
import net.minecraft.client.multiplayer.ClientLevel;
@@ -37,11 +36,11 @@ public class TransformCall {
return meshVertexCount * instancer.getInstanceCount();
}
- void setup() {
+ public void setup() {
instancer.update();
}
- void submitTasks(TaskExecutor executor, DrawBuffer buffer, int startVertex, PoseStack.Pose matrices, ClientLevel level) {
+ public void submitTasks(TaskExecutor executor, DrawBuffer buffer, int startVertex, PoseStack.Pose matrices, ClientLevel level) {
int instances = instancer.getInstanceCount();
while (instances > 0) {
@@ -57,21 +56,21 @@ public class TransformCall
{
}
}
- private void transformRange(ReusableVertexList vertexList, int from, int to, PoseStack.Pose matrices, ClientLevel level) {
+ public void transformRange(ReusableVertexList vertexList, int from, int to, PoseStack.Pose matrices, ClientLevel level) {
transformList(vertexList, instancer.getRange(from, to), matrices, level);
}
- void transformAll(ReusableVertexList vertexList, PoseStack.Pose matrices, ClientLevel level) {
+ public void transformAll(ReusableVertexList vertexList, PoseStack.Pose matrices, ClientLevel level) {
transformList(vertexList, instancer.getAll(), matrices, level);
}
- private void transformList(ReusableVertexList vertexList, List
parts, PoseStack.Pose matrices, ClientLevel level) {
+ public void transformList(ReusableVertexList vertexList, List
parts, PoseStack.Pose matrices, ClientLevel level) {
long anchorPtr = vertexList.ptr();
int totalVertexCount = vertexList.vertexCount();
vertexList.vertexCount(meshVertexCount);
- StructType.VertexTransformer
structVertexTransformer = instancer.type.getVertexTransformer();
+ StructVertexTransformer
structVertexTransformer = instancer.type.getVertexTransformer();
for (P p : parts) {
mesh.copyTo(vertexList.ptr());
@@ -88,34 +87,12 @@ public class TransformCall
{
}
private static void applyMatrices(MutableVertexList vertexList, PoseStack.Pose matrices) {
- Vector4f pos = new Vector4f();
- Vector3f normal = new Vector3f();
-
Matrix4f modelMatrix = matrices.pose();
Matrix3f normalMatrix = matrices.normal();
for (int i = 0; i < vertexList.vertexCount(); i++) {
- pos.set(
- vertexList.x(i),
- vertexList.y(i),
- vertexList.z(i),
- 1f
- );
- pos.transform(modelMatrix);
- vertexList.x(i, pos.x());
- vertexList.y(i, pos.y());
- vertexList.z(i, pos.z());
-
- normal.set(
- vertexList.normalX(i),
- vertexList.normalY(i),
- vertexList.normalZ(i)
- );
- normal.transform(normalMatrix);
- normal.normalize();
- vertexList.normalX(i, normal.x());
- vertexList.normalY(i, normal.y());
- vertexList.normalZ(i, normal.z());
+ VertexTransformations.transformPos(vertexList, i, modelMatrix);
+ VertexTransformations.transformNormal(vertexList, i, normalMatrix);
}
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectComponent.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectComponent.java
index f82f04f41..ecdabd46e 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectComponent.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectComponent.java
@@ -8,6 +8,7 @@ import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.layout.LayoutItem;
import com.jozufozu.flywheel.api.pipeline.Pipeline;
import com.jozufozu.flywheel.api.struct.StructType;
+import com.jozufozu.flywheel.backend.Pipelines;
import com.jozufozu.flywheel.glsl.ShaderSources;
import com.jozufozu.flywheel.glsl.SourceComponent;
import com.jozufozu.flywheel.glsl.SourceFile;
@@ -15,7 +16,6 @@ import com.jozufozu.flywheel.glsl.generate.FnSignature;
import com.jozufozu.flywheel.glsl.generate.GlslBlock;
import com.jozufozu.flywheel.glsl.generate.GlslBuilder;
import com.jozufozu.flywheel.glsl.generate.GlslExpr;
-import com.jozufozu.flywheel.lib.pipeline.Pipelines;
import net.minecraft.resources.ResourceLocation;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java
index b5f9bed66..9636b512b 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectCullingGroup.java
@@ -12,14 +12,14 @@ import static org.lwjgl.opengl.GL45.glVertexArrayElementBuffer;
import static org.lwjgl.opengl.GL45.glVertexArrayVertexBuffer;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.vertex.VertexType;
+import com.jozufozu.flywheel.backend.Pipelines;
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
import com.jozufozu.flywheel.gl.shader.GlProgram;
import com.jozufozu.flywheel.lib.context.Contexts;
-import com.jozufozu.flywheel.lib.pipeline.Pipelines;
import com.jozufozu.flywheel.lib.util.QuadConverter;
public class IndirectCullingGroup
{
@@ -109,7 +109,7 @@ public class IndirectCullingGroup
{
}
buffers.updateCounts(instanceCountThisFrame, drawSet.size());
- meshPool.uploadAll();
+ meshPool.flush();
uploadInstanceData();
uploadIndirectCommands();
@@ -174,7 +174,7 @@ public class IndirectCullingGroup
{
int baseInstance = 0;
for (var batch : drawSet.indirectDraws) {
batch.prepare(baseInstance);
- baseInstance += batch.instancer().instanceCount;
+ baseInstance += batch.instancer().getInstanceCount();
}
return baseInstance;
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java
index bbc352f4c..d9a18a032 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDraw.java
@@ -3,32 +3,48 @@ package com.jozufozu.flywheel.backend.engine.indirect;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.material.Material;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.lib.material.MaterialIndices;
-public final class IndirectDraw
{
+public class IndirectDraw
{
private final IndirectInstancer
instancer;
private final IndirectMeshPool.BufferedMesh mesh;
private final Material material;
private final RenderStage stage;
- int baseInstance = -1;
- final int vertexMaterialID;
- final int fragmentMaterialID;
+ private final int vertexMaterialID;
+ private final int fragmentMaterialID;
- boolean needsFullWrite = true;
+ private int baseInstance = -1;
+ private boolean needsFullWrite = true;
- IndirectDraw(IndirectInstancer
instancer, Material material, RenderStage stage, IndirectMeshPool.BufferedMesh mesh) {
+ public IndirectDraw(IndirectInstancer
instancer, Material material, IndirectMeshPool.BufferedMesh mesh, RenderStage stage) {
this.instancer = instancer;
this.material = material;
- this.stage = stage;
this.mesh = mesh;
+ this.stage = stage;
this.vertexMaterialID = MaterialIndices.getVertexShaderIndex(material);
this.fragmentMaterialID = MaterialIndices.getFragmentShaderIndex(material);
}
+ public IndirectInstancer
instancer() {
+ return instancer;
+ }
+
+ public Material material() {
+ return material;
+ }
+
+ public IndirectMeshPool.BufferedMesh mesh() {
+ return mesh;
+ }
+
+ public RenderStage stage() {
+ return stage;
+ }
+
public void prepare(int baseInstance) {
instancer.update();
if (baseInstance == this.baseInstance) {
@@ -39,7 +55,7 @@ public final class IndirectDraw
{
needsFullWrite = true;
}
- void writeObjects(long objectPtr, long batchIDPtr, int batchID) {
+ public void writeObjects(long objectPtr, long batchIDPtr, int batchID) {
if (needsFullWrite) {
instancer.writeFull(objectPtr, batchIDPtr, batchID);
} else {
@@ -48,7 +64,7 @@ public final class IndirectDraw
{
}
public void writeIndirectCommand(long ptr) {
- var boundingSphere = mesh.mesh.getBoundingSphere();
+ var boundingSphere = mesh.getMesh().getBoundingSphere();
MemoryUtil.memPutInt(ptr, mesh.getIndexCount()); // count
MemoryUtil.memPutInt(ptr + 4, 0); // instanceCount - to be incremented by the compute shader
@@ -59,22 +75,5 @@ public final class IndirectDraw
{
boundingSphere.getToAddress(ptr + 20); // boundingSphere
MemoryUtil.memPutInt(ptr + 36, vertexMaterialID); // vertexMaterialID
MemoryUtil.memPutInt(ptr + 40, fragmentMaterialID); // fragmentMaterialID
-
- }
-
- public IndirectInstancer
instancer() {
- return instancer;
- }
-
- public IndirectMeshPool.BufferedMesh mesh() {
- return mesh;
- }
-
- public Material material() {
- return material;
- }
-
- public RenderStage stage() {
- return stage;
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java
index 73eb23973..49ab8402c 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawManager.java
@@ -6,16 +6,15 @@ import java.util.List;
import java.util.Map;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.model.Model;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.engine.InstancerKey;
import com.jozufozu.flywheel.util.Pair;
public class IndirectDrawManager {
-
private final Map, IndirectInstancer>> instancers = new HashMap<>();
private final List uninitializedInstancers = new ArrayList<>();
private final List> initializedInstancers = new ArrayList<>();
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java
index 8fe598553..7f0080794 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectDrawSet.java
@@ -11,10 +11,9 @@ import java.util.List;
import java.util.Map;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.material.Material;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.lib.material.MaterialIndices;
-import com.jozufozu.flywheel.util.Textures;
public class IndirectDrawSet {
@@ -31,7 +30,7 @@ public class IndirectDrawSet
{
}
public void add(IndirectInstancer
instancer, Material material, RenderStage stage, IndirectMeshPool.BufferedMesh bufferedMesh) {
- indirectDraws.add(new IndirectDraw<>(instancer, material, stage, bufferedMesh));
+ indirectDraws.add(new IndirectDraw<>(instancer, material, bufferedMesh, stage));
determineMultiDraws();
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java
index be3e9bb30..5c53a2261 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java
@@ -7,9 +7,9 @@ import org.lwjgl.opengl.GL32;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.model.Model;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.task.TaskExecutor;
import com.jozufozu.flywheel.gl.GlStateTracker;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java
index 4d50bafc5..e5f6282fa 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectInstancer.java
@@ -2,52 +2,43 @@ package com.jozufozu.flywheel.backend.engine.indirect;
import org.lwjgl.system.MemoryUtil;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
public class IndirectInstancer
extends AbstractInstancer
{
-
- private final long objectStride;
- private final StructWriter
writer;
- int instanceCount = 0;
+ private final long instanceStride;
public IndirectInstancer(StructType
type) {
super(type);
- this.objectStride = type.getLayout()
+ this.instanceStride = type.getLayout()
.getStride();
- writer = type.getWriter();
}
- public boolean isEmpty() {
- return changed.isEmpty() && deleted.isEmpty() && instanceCount == 0;
- }
-
- void update() {
- if (!deleted.isEmpty()) {
- removeDeletedInstances();
- }
-
- instanceCount = data.size();
+ public void update() {
+ removeDeletedInstances();
}
public void writeSparse(long objectPtr, long batchIDPtr, int batchID) {
- final int size = data.size();
+ int count = data.size();
+ StructWriter
writer = type.getWriter();
+ for (int i = changed.nextSetBit(0); i >= 0 && i < count; i = changed.nextSetBit(i + 1)) {
+ // write object
+ writer.write(objectPtr + instanceStride * i, data.get(i));
- for (int i = changed.nextSetBit(0); i >= 0 && i < size; i = changed.nextSetBit(i + 1)) {
- writer.write(objectPtr + i * objectStride, data.get(i));
-
- MemoryUtil.memPutInt(batchIDPtr + i * IndirectBuffers.INT_SIZE, batchID);
+ // write batchID
+ MemoryUtil.memPutInt(batchIDPtr + IndirectBuffers.INT_SIZE * i, batchID);
}
changed.clear();
}
public void writeFull(long objectPtr, long batchIDPtr, int batchID) {
+ StructWriter
writer = type.getWriter();
for (var object : data) {
// write object
writer.write(objectPtr, object);
- objectPtr += objectStride;
+ objectPtr += instanceStride;
// write batchID
MemoryUtil.memPutInt(batchIDPtr, batchID);
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectMeshPool.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectMeshPool.java
index f7da98d36..c966ab56b 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectMeshPool.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectMeshPool.java
@@ -39,6 +39,10 @@ public class IndirectMeshPool {
clientStorage = MemoryBlock.malloc(byteCapacity);
}
+ public VertexType getVertexType() {
+ return vertexType;
+ }
+
/**
* Allocate a model in the arena.
*
@@ -60,24 +64,26 @@ public class IndirectMeshPool {
return meshes.get(mesh);
}
- void uploadAll() {
- if (!dirty) {
- return;
+ public void flush() {
+ if (dirty) {
+ uploadAll();
+ dirty = false;
}
- dirty = false;
+ }
+ private void uploadAll() {
final long ptr = clientStorage.ptr();
int byteIndex = 0;
int baseVertex = 0;
- for (BufferedMesh model : meshList) {
- model.byteIndex = byteIndex;
- model.baseVertex = baseVertex;
+ for (BufferedMesh mesh : meshList) {
+ mesh.byteIndex = byteIndex;
+ mesh.baseVertex = baseVertex;
- model.buffer(ptr);
+ mesh.buffer(ptr);
- byteIndex += model.size();
- baseVertex += model.mesh.getVertexCount();
+ byteIndex += mesh.size();
+ baseVertex += mesh.mesh.getVertexCount();
}
nglNamedBufferSubData(vbo, 0, byteIndex, ptr);
@@ -90,26 +96,18 @@ public class IndirectMeshPool {
meshList.clear();
}
- public VertexType getVertexType() {
- return vertexType;
- }
-
public class BufferedMesh {
- public final Mesh mesh;
+ private final Mesh mesh;
private final int vertexCount;
+
private long byteIndex;
private int baseVertex;
private BufferedMesh(Mesh mesh) {
this.mesh = mesh;
-
vertexCount = mesh.getVertexCount();
}
- private void buffer(long ptr) {
- mesh.write(ptr + byteIndex);
- }
-
public Mesh getMesh() {
return mesh;
}
@@ -129,5 +127,9 @@ public class IndirectMeshPool {
public VertexType getVertexType() {
return vertexType;
}
+
+ private void buffer(long ptr) {
+ mesh.write(ptr + byteIndex);
+ }
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/util/Textures.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/Textures.java
similarity index 89%
rename from src/main/java/com/jozufozu/flywheel/util/Textures.java
rename to src/main/java/com/jozufozu/flywheel/backend/engine/indirect/Textures.java
index f6292e966..7cc18e82e 100644
--- a/src/main/java/com/jozufozu/flywheel/util/Textures.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/Textures.java
@@ -1,4 +1,4 @@
-package com.jozufozu.flywheel.util;
+package com.jozufozu.flywheel.backend.engine.indirect;
import org.lwjgl.opengl.GL32;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/DrawCall.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/DrawCall.java
index 7c86e5f3e..9f152f392 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/DrawCall.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/DrawCall.java
@@ -1,86 +1,50 @@
package com.jozufozu.flywheel.backend.engine.instancing;
-import com.jozufozu.flywheel.api.material.Material;
-import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.gl.GlStateTracker;
import com.jozufozu.flywheel.gl.array.GlVertexArray;
public class DrawCall {
+ private final GPUInstancer> instancer;
+ private final InstancedMeshPool.BufferedMesh mesh;
- final GPUInstancer> instancer;
- final Material material;
private final int meshAttributes;
- InstancedMeshPool.BufferedMesh bufferedMesh;
- GlVertexArray vao;
+ private GlVertexArray vao;
- DrawCall(GPUInstancer> instancer, Material material, InstancedMeshPool.BufferedMesh mesh) {
+ public DrawCall(GPUInstancer> instancer, InstancedMeshPool.BufferedMesh mesh) {
this.instancer = instancer;
- this.material = material;
- this.vao = new GlVertexArray();
- this.bufferedMesh = mesh;
- this.meshAttributes = this.bufferedMesh.getAttributeCount();
- this.vao.enableArrays(this.meshAttributes + instancer.instanceFormat.getAttributeCount());
+ this.mesh = mesh;
+
+ meshAttributes = this.mesh.getAttributeCount();
+ vao = new GlVertexArray();
+ vao.enableArrays(meshAttributes + this.instancer.getAttributeCount());
}
- public Material getMaterial() {
- return material;
- }
-
- public VertexType getVertexType() {
- return bufferedMesh.getVertexType();
+ public boolean isInvalid() {
+ return instancer.isInvalid() || vao == null;
}
public void render() {
- if (invalid()) {
+ if (isInvalid()) {
return;
}
try (var ignored = GlStateTracker.getRestoreState()) {
+ instancer.update();
- this.instancer.update();
+ instancer.bindToVAO(vao, meshAttributes);
- bindInstancerToVAO();
-
- if (this.instancer.glInstanceCount > 0) {
- bufferedMesh.drawInstances(vao, this.instancer.glInstanceCount);
+ if (instancer.getInstanceCount() > 0) {
+ mesh.drawInstances(vao, instancer.getInstanceCount());
}
}
}
- public boolean shouldRemove() {
- return invalid();
- }
-
- /**
- * Only {@code true} if the InstancedModel has been destroyed.
- */
- private boolean invalid() {
- return this.instancer.vbo == null || bufferedMesh == null || vao == null;
- }
-
- private void bindInstancerToVAO() {
- if (!this.instancer.boundTo.add(vao)) {
- return;
- }
-
- var instanceFormat = this.instancer.instanceFormat;
-
- vao.bindAttributes(this.instancer.vbo, this.meshAttributes, instanceFormat, 0L);
-
- for (int i = 0; i < instanceFormat.getAttributeCount(); i++) {
- vao.setAttributeDivisor(this.meshAttributes + i, 1);
- }
- }
-
public void delete() {
- if (invalid()) {
+ if (vao == null) {
return;
}
vao.delete();
- bufferedMesh.delete();
-
vao = null;
- bufferedMesh = null;
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java
index 55b48a75c..dbd5040c1 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/GPUInstancer.java
@@ -4,8 +4,8 @@ import java.util.HashSet;
import java.util.Set;
import com.jozufozu.flywheel.Flywheel;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.layout.BufferLayout;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
@@ -16,17 +16,24 @@ import com.jozufozu.flywheel.gl.buffer.GlBufferUsage;
import com.jozufozu.flywheel.gl.buffer.MappedBuffer;
public class GPUInstancer
extends AbstractInstancer
{
+ private final BufferLayout instanceFormat;
+ private final int instanceStride;
- final BufferLayout instanceFormat;
- final Set boundTo = new HashSet<>();
- GlBuffer vbo;
- int glInstanceCount = 0;
-
- boolean anyToUpdate;
+ private final Set boundTo = new HashSet<>();
+ private GlBuffer vbo;
public GPUInstancer(StructType type) {
super(type);
- this.instanceFormat = type.getLayout();
+ instanceFormat = type.getLayout();
+ instanceStride = instanceFormat.getStride();
+ }
+
+ public int getAttributeCount() {
+ return instanceFormat.getAttributeCount();
+ }
+
+ public boolean isInvalid() {
+ return vbo == null;
}
public void init() {
@@ -35,63 +42,59 @@ public class GPUInstancer
extends AbstractInstancer
{
}
vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER, GlBufferUsage.DYNAMIC_DRAW);
- vbo.setGrowthMargin(instanceFormat.getStride() * 16);
+ vbo.setGrowthMargin(instanceStride * 16);
}
- public boolean isEmpty() {
- return deleted.isEmpty() && changed.isEmpty() && glInstanceCount == 0;
+ public void update() {
+ removeDeletedInstances();
+ ensureBufferCapacity();
+ updateBuffer();
}
- void update() {
- if (!deleted.isEmpty()) {
- removeDeletedInstances();
- }
-
- if (checkAndGrowBuffer()) {
- // The instance vbo has moved, so we need to re-bind attributes
+ private void ensureBufferCapacity() {
+ int count = data.size();
+ int byteSize = instanceStride * count;
+ if (vbo.ensureCapacity(byteSize)) {
+ // The vbo has moved, so we need to re-bind attributes
boundTo.clear();
}
-
- if (!changed.isEmpty()) {
- clearAndUpdateBuffer();
- }
-
- glInstanceCount = data.size();
}
- private void clearAndUpdateBuffer() {
- final int size = data.size();
- final long clearStart = (long) size * instanceFormat.getStride();
- final long clearLength = vbo.getSize() - clearStart;
+ private void updateBuffer() {
+ if (changed.isEmpty()) {
+ return;
+ }
+
+ int count = data.size();
+ long clearStart = instanceStride * (long) count;
+ long clearLength = vbo.getSize() - clearStart;
try (MappedBuffer buf = vbo.map()) {
buf.clear(clearStart, clearLength);
- if (size > 0) {
- final long ptr = buf.getPtr();
- final long stride = type.getLayout()
- .getStride();
- final StructWriter
writer = type.getWriter();
+ long ptr = buf.getPtr();
+ StructWriter
writer = type.getWriter();
- for (int i = changed.nextSetBit(0); i >= 0 && i < size; i = changed.nextSetBit(i + 1)) {
- writer.write(ptr + i * stride, data.get(i));
- }
- changed.clear();
+ for (int i = changed.nextSetBit(0); i >= 0 && i < count; i = changed.nextSetBit(i + 1)) {
+ writer.write(ptr + instanceStride * i, data.get(i));
}
+
+ changed.clear();
} catch (Exception e) {
Flywheel.LOGGER.error("Error updating GPUInstancer:", e);
}
}
- /**
- * @return {@code true} if the buffer moved.
- */
- private boolean checkAndGrowBuffer() {
- int size = this.data.size();
- int stride = instanceFormat.getStride();
- int requiredSize = size * stride;
+ public void bindToVAO(GlVertexArray vao, int attributeOffset) {
+ if (!boundTo.add(vao)) {
+ return;
+ }
- return vbo.ensureCapacity(requiredSize);
+ vao.bindAttributes(vbo, attributeOffset, instanceFormat, 0L);
+
+ for (int i = 0; i < instanceFormat.getAttributeCount(); i++) {
+ vao.setAttributeDivisor(attributeOffset + i, 1);
+ }
}
public void delete() {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedMeshPool.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedMeshPool.java
index e9f9320c2..603b7bce8 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedMeshPool.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedMeshPool.java
@@ -39,9 +39,12 @@ public class InstancedMeshPool {
public InstancedMeshPool(VertexType vertexType) {
this.vertexType = vertexType;
int stride = vertexType.getLayout().getStride();
- this.vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
+ vbo = new GlBuffer(GlBufferType.ARRAY_BUFFER);
+ vbo.setGrowthMargin(stride * 32);
+ }
- this.vbo.setGrowthMargin(stride * 32);
+ public VertexType getVertexType() {
+ return vertexType;
}
/**
@@ -161,10 +164,6 @@ public class InstancedMeshPool {
pendingUpload.clear();
}
- public VertexType getVertexType() {
- return vertexType;
- }
-
@Override
public String toString() {
return "InstancedMeshPool{" + "vertexType=" + vertexType + ", byteSize=" + byteSize + ", meshCount=" + meshes.size() + '}';
@@ -210,10 +209,6 @@ public class InstancedMeshPool {
boundTo.clear();
}
- public void drawCall(GlVertexArray vao) {
- drawInstances(vao, 1);
- }
-
public void drawInstances(GlVertexArray vao, int instanceCount) {
if (isEmpty()) {
return;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingDrawManager.java
index 10c3fd563..d6165ddb8 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingDrawManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingDrawManager.java
@@ -14,16 +14,15 @@ import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ListMultimap;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.model.Mesh;
import com.jozufozu.flywheel.api.model.Model;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.backend.engine.InstancerKey;
public class InstancingDrawManager {
-
private final Map, GPUInstancer>> instancers = new HashMap<>();
private final List uninitializedInstancers = new ArrayList<>();
private final List> initializedInstancers = new ArrayList<>();
@@ -48,9 +47,6 @@ public class InstancingDrawManager {
public void flush() {
for (var instancer : uninitializedInstancers) {
- instancer.instancer()
- .init();
-
add(instancer.instancer(), instancer.model(), instancer.stage());
}
uninitializedInstancers.clear();
@@ -80,11 +76,13 @@ public class InstancingDrawManager {
}
private void add(GPUInstancer> instancer, Model model, RenderStage stage) {
+ instancer.init();
DrawSet drawSet = drawSets.computeIfAbsent(stage, DrawSet::new);
var meshes = model.getMeshes();
for (var entry : meshes.entrySet()) {
- DrawCall drawCall = new DrawCall(instancer, entry.getKey(), alloc(entry.getValue()));
- var shaderState = new ShaderState(drawCall.getMaterial(), drawCall.getVertexType(), drawCall.instancer.type);
+ var mesh = alloc(entry.getValue());
+ ShaderState shaderState = new ShaderState(entry.getKey(), mesh.getVertexType(), instancer.type);
+ DrawCall drawCall = new DrawCall(instancer, mesh);
drawSet.put(shaderState, drawCall);
}
initializedInstancers.add(instancer);
@@ -96,7 +94,6 @@ public class InstancingDrawManager {
}
public static class DrawSet implements Iterable>> {
-
public static final DrawSet EMPTY = new DrawSet(ImmutableListMultimap.of());
private final ListMultimap drawCalls;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java
index 8cfbb174b..80e0a6b3a 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java
@@ -8,17 +8,17 @@ import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.event.RenderStage;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.model.Model;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.task.TaskExecutor;
+import com.jozufozu.flywheel.backend.Pipelines;
import com.jozufozu.flywheel.backend.compile.FlwCompiler;
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
import com.jozufozu.flywheel.gl.GlStateTracker;
import com.jozufozu.flywheel.gl.GlTextureUnit;
import com.jozufozu.flywheel.lib.material.MaterialIndices;
-import com.jozufozu.flywheel.lib.pipeline.Pipelines;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Camera;
@@ -47,7 +47,7 @@ public class InstancingEngine implements Engine {
@Override
public void beginFrame(TaskExecutor executor, RenderContext context) {
- try (var restoreState = GlStateTracker.getRestoreState()) {
+ try (var state = GlStateTracker.getRestoreState()) {
drawManager.flush();
}
}
@@ -60,7 +60,7 @@ public class InstancingEngine implements Engine {
return;
}
- try (var restoreState = GlStateTracker.getRestoreState()) {
+ try (var state = GlStateTracker.getRestoreState()) {
setup();
render(drawSet);
@@ -83,7 +83,7 @@ public class InstancingEngine implements Engine {
var shader = entry.getKey();
var drawCalls = entry.getValue();
- drawCalls.removeIf(DrawCall::shouldRemove);
+ drawCalls.removeIf(DrawCall::isInvalid);
if (drawCalls.isEmpty()) {
continue;
@@ -102,9 +102,9 @@ public class InstancingEngine implements Engine {
}
private void setup(ShaderState desc) {
- var vertexType = desc.vertex();
- var structType = desc.instance();
var material = desc.material();
+ var vertexType = desc.vertexType();
+ var structType = desc.instanceType();
var program = FlwCompiler.INSTANCE.getPipelineProgram(vertexType, structType, context, Pipelines.INSTANCED_ARRAYS);
UniformBuffer.syncAndBind(program);
diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/ShaderState.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/ShaderState.java
index c38be8946..420cfac1b 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/ShaderState.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/ShaderState.java
@@ -4,5 +4,5 @@ import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.vertex.VertexType;
-public record ShaderState(Material material, VertexType vertex, StructType> instance) {
+public record ShaderState(Material material, VertexType vertexType, StructType> instanceType) {
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/task/FlwTaskExecutor.java b/src/main/java/com/jozufozu/flywheel/backend/task/FlwTaskExecutor.java
new file mode 100644
index 000000000..b88a1be76
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/task/FlwTaskExecutor.java
@@ -0,0 +1,18 @@
+package com.jozufozu.flywheel.backend.task;
+
+public class FlwTaskExecutor {
+ private static ParallelTaskExecutor executor;
+
+ /**
+ * Get a thread pool for running Flywheel related work in parallel.
+ * @return A global Flywheel thread pool.
+ */
+ public static ParallelTaskExecutor get() {
+ if (executor == null) {
+ executor = new ParallelTaskExecutor("Flywheel");
+ executor.startWorkers();
+ }
+
+ return executor;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/task/ParallelTaskExecutor.java b/src/main/java/com/jozufozu/flywheel/backend/task/ParallelTaskExecutor.java
index e8917fcad..351b3d8b9 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/task/ParallelTaskExecutor.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/task/ParallelTaskExecutor.java
@@ -146,6 +146,28 @@ public class ParallelTaskExecutor implements TaskExecutor {
}
}
+ public void discardAndAwait() {
+ // Discard everyone else's work...
+ while (taskQueue.pollLast() != null) {
+ synchronized (tasksCompletedNotifier) {
+ if (--incompleteTaskCounter == 0) {
+ tasksCompletedNotifier.notifyAll();
+ }
+ }
+ }
+
+ // and wait for any stragglers.
+ synchronized (tasksCompletedNotifier) {
+ while (incompleteTaskCounter > 0) {
+ try {
+ tasksCompletedNotifier.wait();
+ } catch (InterruptedException e) {
+ //
+ }
+ }
+ }
+ }
+
@Nullable
private Runnable getNextTask() {
Runnable task = taskQueue.pollFirst();
diff --git a/src/main/java/com/jozufozu/flywheel/config/BackendArgument.java b/src/main/java/com/jozufozu/flywheel/config/BackendArgument.java
index 64e2bd23d..35e783735 100644
--- a/src/main/java/com/jozufozu/flywheel/config/BackendArgument.java
+++ b/src/main/java/com/jozufozu/flywheel/config/BackendArgument.java
@@ -9,20 +9,19 @@ import com.mojang.brigadier.StringReader;
import com.mojang.brigadier.arguments.ArgumentType;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
-import com.mojang.brigadier.exceptions.Dynamic2CommandExceptionType;
+import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import net.minecraft.commands.SharedSuggestionProvider;
-import net.minecraft.network.chat.TranslatableComponent;
+import net.minecraft.network.chat.TextComponent;
import net.minecraft.resources.ResourceLocation;
public class BackendArgument implements ArgumentType {
private static final List STRING_IDS = Backend.REGISTRY.getAllIds().stream().map(ResourceLocation::toString).toList();
- private static final Dynamic2CommandExceptionType INVALID = new Dynamic2CommandExceptionType((found, constants) -> {
- // TODO: don't steal lang
- return new TranslatableComponent("commands.forge.arguments.enum.invalid", constants, found);
+ public static final DynamicCommandExceptionType ERROR_UNKNOWN_BACKEND = new DynamicCommandExceptionType(arg -> {
+ return new TextComponent("Unknown backend '" + arg + "'");
});
public static final BackendArgument INSTANCE = new BackendArgument();
@@ -33,7 +32,7 @@ public class BackendArgument implements ArgumentType {
Backend backend = Backend.REGISTRY.get(id);
if (backend == null) {
- throw INVALID.createWithContext(reader, id.toString(), STRING_IDS);
+ throw ERROR_UNKNOWN_BACKEND.createWithContext(reader, id.toString());
}
return backend;
diff --git a/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java b/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java
index 9d534c029..084c1f707 100644
--- a/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java
+++ b/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java
@@ -9,7 +9,7 @@ import org.slf4j.Logger;
import com.jozufozu.flywheel.glsl.ShaderLoadingException;
import com.jozufozu.flywheel.glsl.SourceFile;
import com.jozufozu.flywheel.glsl.span.Span;
-import com.jozufozu.flywheel.util.FlwUtil;
+import com.jozufozu.flywheel.lib.math.MoreMath;
import com.jozufozu.flywheel.util.StringUtil;
import com.mojang.logging.LogUtils;
@@ -97,14 +97,14 @@ public class ErrorReporter {
int size = lines.size();
- int maxWidth = FlwUtil.numDigits(size) + 1;
+ int maxWidth = MoreMath.numDigits(size) + 1;
StringBuilder builder = new StringBuilder().append('\n');
for (int i = 0; i < size; i++) {
builder.append(i)
- .append(StringUtil.repeatChar(' ', maxWidth - FlwUtil.numDigits(i)))
+ .append(StringUtil.repeatChar(' ', maxWidth - MoreMath.numDigits(i)))
.append("| ")
.append(lines.get(i))
.append('\n');
diff --git a/src/main/java/com/jozufozu/flywheel/handler/EntityWorldHandler.java b/src/main/java/com/jozufozu/flywheel/handler/EntityWorldHandler.java
index fd4895fda..9cefeb4a3 100644
--- a/src/main/java/com/jozufozu/flywheel/handler/EntityWorldHandler.java
+++ b/src/main/java/com/jozufozu/flywheel/handler/EntityWorldHandler.java
@@ -1,7 +1,7 @@
package com.jozufozu.flywheel.handler;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
+import com.jozufozu.flywheel.util.FlwUtil;
import net.minecraft.world.level.Level;
import net.minecraftforge.event.entity.EntityJoinWorldEvent;
@@ -14,7 +14,7 @@ public class EntityWorldHandler {
return;
}
- if (BackendUtil.canUseInstancing(level)) {
+ if (FlwUtil.canUseInstancing(level)) {
InstancedRenderDispatcher.getEntities(level)
.queueAdd(event.getEntity());
}
@@ -26,7 +26,7 @@ public class EntityWorldHandler {
return;
}
- if (BackendUtil.canUseInstancing(level)) {
+ if (FlwUtil.canUseInstancing(level)) {
InstancedRenderDispatcher.getEntities(level)
.remove(event.getEntity());
}
diff --git a/src/main/java/com/jozufozu/flywheel/handler/ForgeEvents.java b/src/main/java/com/jozufozu/flywheel/handler/ForgeEvents.java
index 61e78fdc1..af04a70ed 100644
--- a/src/main/java/com/jozufozu/flywheel/handler/ForgeEvents.java
+++ b/src/main/java/com/jozufozu/flywheel/handler/ForgeEvents.java
@@ -3,10 +3,10 @@ package com.jozufozu.flywheel.handler;
import java.util.ArrayList;
import com.jozufozu.flywheel.Flywheel;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.lib.light.LightUpdater;
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
+import com.jozufozu.flywheel.util.FlwUtil;
import com.jozufozu.flywheel.util.StringUtil;
import com.jozufozu.flywheel.util.WorldAttached;
@@ -33,7 +33,7 @@ public class ForgeEvents {
}
public static void tickLight(TickEvent.ClientTickEvent event) {
- if (event.phase == TickEvent.Phase.END && BackendUtil.isGameActive()) {
+ if (event.phase == TickEvent.Phase.END && FlwUtil.isGameActive()) {
LightUpdater.get(Minecraft.getInstance().level)
.tick();
}
diff --git a/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java b/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java
index c7a573b22..c2e4c73d8 100644
--- a/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java
+++ b/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java
@@ -3,14 +3,33 @@ package com.jozufozu.flywheel.impl;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
+import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.backend.Backend;
+import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
+import com.jozufozu.flywheel.backend.Backends;
import com.jozufozu.flywheel.config.FlwConfig;
-import com.jozufozu.flywheel.lib.backend.Backends;
+import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
+import com.jozufozu.flywheel.lib.backend.SimpleBackend;
import com.mojang.logging.LogUtils;
+import net.minecraft.ChatFormatting;
+import net.minecraft.client.multiplayer.ClientLevel;
+import net.minecraft.network.chat.TextComponent;
+import net.minecraftforge.fml.CrashReportCallables;
+
public final class BackendManagerImpl {
private static final Logger LOGGER = LogUtils.getLogger();
+
+ private static final Backend OFF_BACKEND = SimpleBackend.builder()
+ .engineMessage(new TextComponent("Disabled Flywheel").withStyle(ChatFormatting.RED))
+ .engineFactory(level -> {
+ throw new IllegalStateException("Cannot create engine when backend is off.");
+ })
+ .supported(() -> true)
+ .register(Flywheel.rl("off"));
+
private static final Backend DEFAULT_BACKEND = findDefaultBackend();
+
private static Backend backend;
@Nullable
@@ -19,17 +38,35 @@ public final class BackendManagerImpl {
}
public static boolean isOn() {
- return backend != null && backend != Backends.OFF;
+ return backend != null && backend != OFF_BACKEND;
}
- public static void refresh() {
- backend = chooseBackend();
+ public static Backend getOffBackend() {
+ return OFF_BACKEND;
}
public static Backend getDefaultBackend() {
return DEFAULT_BACKEND;
}
+ private static Backend findDefaultBackend() {
+ // TODO: Automatically select the best default config based on the user's driver
+ // TODO: Figure out how this will work if custom backends are registered and without hardcoding the default backends
+ return Backends.INDIRECT;
+ }
+
+ public static void onReloadRenderers(ReloadRenderersEvent event) {
+ refresh(event.getLevel());
+ }
+
+ public static void refresh(@Nullable ClientLevel level) {
+ backend = chooseBackend();
+
+ if (level != null) {
+ InstancedRenderDispatcher.resetInstanceWorld(level);
+ }
+ }
+
private static Backend chooseBackend() {
var preferred = FlwConfig.get().getBackend();
var actual = preferred.findFallback();
@@ -41,21 +78,17 @@ public final class BackendManagerImpl {
return actual;
}
- private static Backend findDefaultBackend() {
- // TODO: Automatically select the best default config based on the user's driver
- // TODO: Figure out how this will work if custom backends are registered
- return Backends.INDIRECT;
- }
-
- public static String getBackendNameForCrashReport() {
- if (backend == null) {
- return "Uninitialized";
- }
- var backendId = Backend.REGISTRY.getId(backend);
- if (backendId == null) {
- return "Unregistered";
- }
- return backendId.toString();
+ public static void init() {
+ CrashReportCallables.registerCrashCallable("Flywheel Backend", () -> {
+ if (backend == null) {
+ return "Uninitialized";
+ }
+ var backendId = Backend.REGISTRY.getId(backend);
+ if (backendId == null) {
+ return "Unregistered";
+ }
+ return backendId.toString();
+ });
}
private BackendManagerImpl() {
diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/InstanceWorld.java
index 635fff41d..e974d0b69 100644
--- a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstanceWorld.java
+++ b/src/main/java/com/jozufozu/flywheel/impl/instancing/InstanceWorld.java
@@ -11,8 +11,8 @@ import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.TickableInstance;
import com.jozufozu.flywheel.api.instance.effect.Effect;
-import com.jozufozu.flywheel.api.task.TaskExecutor;
-import com.jozufozu.flywheel.backend.BackendUtil;
+import com.jozufozu.flywheel.backend.task.FlwTaskExecutor;
+import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
import com.jozufozu.flywheel.config.FlwCommands;
import com.jozufozu.flywheel.config.FlwConfig;
import com.jozufozu.flywheel.impl.instancing.manager.BlockEntityInstanceManager;
@@ -27,9 +27,10 @@ import net.minecraft.world.level.block.entity.BlockEntity;
/**
* A manager class for a single world where instancing is supported.
*/
-public class InstanceWorld {
+// AutoCloseable is implemented to prevent leaking this object from WorldAttached
+public class InstanceWorld implements AutoCloseable {
private final Engine engine;
- private final TaskExecutor taskExecutor;
+ private final ParallelTaskExecutor taskExecutor;
private final InstanceManager blockEntities;
private final InstanceManager entities;
@@ -37,7 +38,7 @@ public class InstanceWorld {
public InstanceWorld(LevelAccessor level) {
engine = BackendManager.getBackend().createEngine(level);
- taskExecutor = BackendUtil.getTaskExecutor();
+ taskExecutor = FlwTaskExecutor.get();
blockEntities = new BlockEntityInstanceManager(engine);
entities = new EntityInstanceManager(engine);
@@ -127,9 +128,15 @@ public class InstanceWorld {
* Free all acquired resources and invalidate this instance world.
*/
public void delete() {
+ taskExecutor.discardAndAwait();
blockEntities.invalidate();
entities.invalidate();
effects.invalidate();
engine.delete();
}
+
+ @Override
+ public void close() {
+ delete();
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancedRenderDispatcher.java
index b44513e12..11aaaabd3 100644
--- a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancedRenderDispatcher.java
+++ b/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancedRenderDispatcher.java
@@ -3,14 +3,13 @@ package com.jozufozu.flywheel.impl.instancing;
import java.util.List;
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
-import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.api.event.RenderStageEvent;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.effect.Effect;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.extension.ClientLevelExtension;
import com.jozufozu.flywheel.impl.instancing.manager.InstanceManager;
-import com.jozufozu.flywheel.util.AnimationTickHolder;
+import com.jozufozu.flywheel.lib.util.AnimationTickHolder;
+import com.jozufozu.flywheel.util.FlwUtil;
import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.client.Minecraft;
@@ -34,7 +33,7 @@ public class InstancedRenderDispatcher {
return;
}
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
return;
}
@@ -49,7 +48,7 @@ public class InstancedRenderDispatcher {
*/
public static void queueUpdate(Entity entity) {
Level level = entity.level;
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
return;
}
@@ -63,7 +62,7 @@ public class InstancedRenderDispatcher {
* @param effect The effect whose instance you want to update.
*/
public static void queueUpdate(LevelAccessor level, Effect effect) {
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
return;
}
@@ -77,7 +76,7 @@ public class InstancedRenderDispatcher {
* @throws IllegalStateException if the backend is off
*/
private static InstanceWorld getInstanceWorld(LevelAccessor level) {
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
throw new IllegalStateException("Cannot retrieve instance world when backend is off!");
}
return INSTANCE_WORLDS.get(level);
@@ -100,7 +99,7 @@ public class InstancedRenderDispatcher {
}
public static void tick(TickEvent.ClientTickEvent event) {
- if (!BackendUtil.isGameActive() || event.phase == TickEvent.Phase.START) {
+ if (!FlwUtil.isGameActive() || event.phase == TickEvent.Phase.START) {
return;
}
@@ -117,7 +116,7 @@ public class InstancedRenderDispatcher {
}
Level level = cameraEntity.level;
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
return;
}
@@ -129,12 +128,12 @@ public class InstancedRenderDispatcher {
}
public static void onBeginFrame(BeginFrameEvent event) {
- if (!BackendUtil.isGameActive()) {
+ if (!FlwUtil.isGameActive()) {
return;
}
ClientLevel level = event.getContext().level();
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
return;
}
@@ -143,26 +142,17 @@ public class InstancedRenderDispatcher {
public static void onRenderStage(RenderStageEvent event) {
ClientLevel level = event.getContext().level();
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
return;
}
INSTANCE_WORLDS.get(level).renderStage(event.getContext(), event.getStage());
}
- public static void onReloadRenderers(ReloadRenderersEvent event) {
- ClientLevel level = event.getLevel();
- if (level == null) {
- return;
- }
-
- resetInstanceWorld(level);
- }
-
public static void resetInstanceWorld(ClientLevel level) {
INSTANCE_WORLDS.remove(level, InstanceWorld::delete);
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
return;
}
@@ -175,7 +165,7 @@ public class InstancedRenderDispatcher {
public static void addDebugInfo(List info) {
ClientLevel level = Minecraft.getInstance().level;
- if (BackendUtil.canUseInstancing(level)) {
+ if (FlwUtil.canUseInstancing(level)) {
INSTANCE_WORLDS.get(level).addDebugInfo(info);
} else {
info.add("Disabled");
diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/BlockEntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/BlockEntityInstanceManager.java
index e43961527..cf4a7ba84 100644
--- a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/BlockEntityInstanceManager.java
+++ b/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/BlockEntityInstanceManager.java
@@ -8,10 +8,10 @@ import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.instance.BlockEntityInstance;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper;
import com.jozufozu.flywheel.impl.instancing.storage.One2OneStorage;
import com.jozufozu.flywheel.impl.instancing.storage.Storage;
+import com.jozufozu.flywheel.util.FlwUtil;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@@ -66,7 +66,7 @@ public class BlockEntityInstanceManager extends InstanceManager {
return false;
}
- if (BackendUtil.isFlywheelLevel(level)) {
+ if (FlwUtil.isFlywheelLevel(level)) {
BlockPos pos = blockEntity.getBlockPos();
BlockGetter existingChunk = level.getChunkForCollisions(pos.getX() >> 4, pos.getZ() >> 4);
diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/EntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/EntityInstanceManager.java
index b76c1966d..5e1474f55 100644
--- a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/EntityInstanceManager.java
+++ b/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/EntityInstanceManager.java
@@ -5,10 +5,10 @@ import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.instance.Instance;
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper;
import com.jozufozu.flywheel.impl.instancing.storage.One2OneStorage;
import com.jozufozu.flywheel.impl.instancing.storage.Storage;
+import com.jozufozu.flywheel.util.FlwUtil;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.level.Level;
@@ -53,7 +53,7 @@ public class EntityInstanceManager extends InstanceManager {
Level level = entity.level;
- return BackendUtil.isFlywheelLevel(level);
+ return FlwUtil.isFlywheelLevel(level);
}
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/InstanceManager.java
index 05a90f292..ff0c5535d 100644
--- a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/InstanceManager.java
+++ b/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/InstanceManager.java
@@ -64,6 +64,14 @@ public abstract class InstanceManager {
queue.add(Transaction.add(obj));
}
+ public void remove(T obj) {
+ getStorage().remove(obj);
+ }
+
+ public void queueRemove(T obj) {
+ queue.add(Transaction.remove(obj));
+ }
+
/**
* Update the instance associated with an object.
*
@@ -91,10 +99,6 @@ public abstract class InstanceManager {
queue.add(Transaction.update(obj));
}
- public void remove(T obj) {
- getStorage().remove(obj);
- }
-
public void recreateAll() {
getStorage().recreateAll();
}
diff --git a/src/main/java/com/jozufozu/flywheel/impl/vertex/InferredVertexListImpl.java b/src/main/java/com/jozufozu/flywheel/impl/vertex/InferredVertexListImpl.java
index 125143446..3f541d157 100644
--- a/src/main/java/com/jozufozu/flywheel/impl/vertex/InferredVertexListImpl.java
+++ b/src/main/java/com/jozufozu/flywheel/impl/vertex/InferredVertexListImpl.java
@@ -4,7 +4,7 @@ import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.lib.format.AbstractVertexList;
-import com.jozufozu.flywheel.util.RenderMath;
+import com.jozufozu.flywheel.lib.math.RenderMath;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.LightTexture;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/backend/SimpleBackend.java b/src/main/java/com/jozufozu/flywheel/lib/backend/SimpleBackend.java
index 07aff3df7..8f1f80703 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/backend/SimpleBackend.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/backend/SimpleBackend.java
@@ -7,6 +7,7 @@ import java.util.function.Supplier;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.backend.Backend;
+import com.jozufozu.flywheel.api.backend.BackendManager;
import com.jozufozu.flywheel.api.backend.Engine;
import com.jozufozu.flywheel.api.pipeline.Pipeline;
@@ -66,7 +67,7 @@ public class SimpleBackend implements Backend {
public static class Builder {
private Component engineMessage;
private Function engineFactory;
- private Supplier fallback;
+ private Supplier fallback = BackendManager::getOffBackend;
private BooleanSupplier isSupported;
private Pipeline pipelineShader;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/box/ImmutableBox.java b/src/main/java/com/jozufozu/flywheel/lib/box/ImmutableBox.java
index e6cfc46dc..0ed8fbc22 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/box/ImmutableBox.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/box/ImmutableBox.java
@@ -1,6 +1,6 @@
package com.jozufozu.flywheel.lib.box;
-import static com.jozufozu.flywheel.util.RenderMath.isPowerOf2;
+import static com.jozufozu.flywheel.lib.math.RenderMath.isPowerOf2;
import net.minecraft.world.phys.AABB;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/box/MutableBox.java b/src/main/java/com/jozufozu/flywheel/lib/box/MutableBox.java
index f052647c8..e8300bcb6 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/box/MutableBox.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/box/MutableBox.java
@@ -2,7 +2,7 @@ package com.jozufozu.flywheel.lib.box;
import java.util.Collection;
-import com.jozufozu.flywheel.util.RenderMath;
+import com.jozufozu.flywheel.lib.math.RenderMath;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -19,7 +19,6 @@ public class MutableBox implements ImmutableBox {
private int maxZ;
public MutableBox() {
-
}
public MutableBox(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
diff --git a/src/main/java/com/jozufozu/flywheel/lib/context/Contexts.java b/src/main/java/com/jozufozu/flywheel/lib/context/Contexts.java
index a234f276c..89207df19 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/context/Contexts.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/context/Contexts.java
@@ -1,27 +1,29 @@
package com.jozufozu.flywheel.lib.context;
+import org.jetbrains.annotations.ApiStatus;
+
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.context.Context;
import com.jozufozu.flywheel.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
-public class Contexts {
+public final class Contexts {
public static final SimpleContext WORLD = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.WORLD_FRAGMENT));
public static final SimpleContext CRUMBLING = Context.REGISTRY.registerAndGet(new SimpleContext(Files.WORLD_VERTEX, Files.CRUMBLING_FRAGMENT));
+ @ApiStatus.Internal
public static void init() {
- // noop
}
- public static class Files {
+ public static final class Files {
public static final ResourceLocation WORLD_VERTEX = ResourceUtil.subPath(Names.WORLD, ".vert");
public static final ResourceLocation WORLD_FRAGMENT = ResourceUtil.subPath(Names.WORLD, ".frag");
public static final ResourceLocation CRUMBLING_VERTEX = ResourceUtil.subPath(Names.CRUMBLING, ".vert");
public static final ResourceLocation CRUMBLING_FRAGMENT = ResourceUtil.subPath(Names.CRUMBLING, ".frag");
}
- public static class Names {
+ public static final class Names {
public static final ResourceLocation WORLD = Flywheel.rl("context/world");
public static final ResourceLocation CRUMBLING = Flywheel.rl("context/crumbling");
}
diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/BlockVertexList.java b/src/main/java/com/jozufozu/flywheel/lib/format/BlockVertexList.java
index 903f4bff7..45b56f035 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/format/BlockVertexList.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/format/BlockVertexList.java
@@ -3,7 +3,7 @@ package com.jozufozu.flywheel.lib.format;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
-import com.jozufozu.flywheel.util.RenderMath;
+import com.jozufozu.flywheel.lib.math.RenderMath;
import net.minecraft.client.renderer.texture.OverlayTexture;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/Formats.java b/src/main/java/com/jozufozu/flywheel/lib/format/Formats.java
index d48980171..7955bbb15 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/format/Formats.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/format/Formats.java
@@ -1,25 +1,27 @@
package com.jozufozu.flywheel.lib.format;
+import org.jetbrains.annotations.ApiStatus;
+
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
-public class Formats {
+public final class Formats {
public static final BlockVertex BLOCK = VertexType.REGISTRY.registerAndGet(new BlockVertex());
public static final PosTexNormalVertex POS_TEX_NORMAL = VertexType.REGISTRY.registerAndGet(new PosTexNormalVertex());
+ @ApiStatus.Internal
public static void init() {
- // noop
}
- public static class Files {
+ public static final class Files {
public static final ResourceLocation BLOCK_LAYOUT = ResourceUtil.subPath(Names.BLOCK, ".vert");
public static final ResourceLocation POS_TEX_NORMAL_LAYOUT = ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert");
}
- public static class Names {
+ public static final class Names {
public static final ResourceLocation BLOCK = Flywheel.rl("layout/block");
public static final ResourceLocation POS_TEX_NORMAL = Flywheel.rl("layout/pos_tex_normal");
}
diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertexList.java b/src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertexList.java
index 6e69bf9a9..5581d5844 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertexList.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertexList.java
@@ -3,7 +3,7 @@ package com.jozufozu.flywheel.lib.format;
import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
-import com.jozufozu.flywheel.util.RenderMath;
+import com.jozufozu.flywheel.lib.math.RenderMath;
import net.minecraft.client.renderer.LightTexture;
import net.minecraft.client.renderer.texture.OverlayTexture;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/layout/CommonItems.java b/src/main/java/com/jozufozu/flywheel/lib/layout/CommonItems.java
index 3f289300a..bd6165595 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/layout/CommonItems.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/layout/CommonItems.java
@@ -5,7 +5,6 @@ import com.jozufozu.flywheel.gl.array.VertexAttributeF;
import com.jozufozu.flywheel.gl.array.VertexAttributeI;
public class CommonItems {
-
private static final String VEC2_TYPE = "vec2";
private static final String VEC3_TYPE = "vec3";
private static final String VEC4_TYPE = "vec4";
@@ -16,6 +15,7 @@ public class CommonItems {
private static final String FLOAT_TYPE = "float";
private static final String UINT_TYPE = "uint";
private static final String LIGHT_COORD_TYPE = "LightCoord";
+
public static final VecInput LIGHT_COORD = VecInput.builder()
.vertexAttribute(new VertexAttributeI(GlNumericType.USHORT, 2))
.typeName(IVEC2_TYPE)
@@ -69,8 +69,4 @@ public class CommonItems {
public static final MatInput MAT3 = new MatInput(3, 3, "mat3", "Mat3F", "unpackMat3F");
public static final MatInput MAT4 = new MatInput(4, 4, "mat4", "Mat4F", "unpackMat4F");
-
- private static class Unpacking {
-
- }
}
diff --git a/src/main/java/com/jozufozu/flywheel/lib/light/LightUpdater.java b/src/main/java/com/jozufozu/flywheel/lib/light/LightUpdater.java
index 52bba12df..3bd003cd6 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/light/LightUpdater.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/light/LightUpdater.java
@@ -5,7 +5,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.stream.Stream;
-import com.jozufozu.flywheel.backend.BackendUtil;
+import com.jozufozu.flywheel.backend.task.FlwTaskExecutor;
import com.jozufozu.flywheel.lib.box.ImmutableBox;
import com.jozufozu.flywheel.lib.task.WorkGroup;
import com.jozufozu.flywheel.util.FlwUtil;
@@ -23,7 +23,6 @@ import net.minecraft.world.level.LightLayer;
* {@link LightUpdated} for LightUpdater to work with them.
*/
public class LightUpdater {
-
private static final WorldAttached LEVELS = new WorldAttached<>(LightUpdater::new);
private final LevelAccessor level;
@@ -68,7 +67,7 @@ public class LightUpdater {
}
})
.onComplete(() -> listeners.forEach(this::addListener))
- .execute(BackendUtil.getTaskExecutor());
+ .execute(FlwTaskExecutor.get());
}
/**
diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java b/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java
index 78a619dda..61baac3a7 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/material/MaterialIndices.java
@@ -21,7 +21,7 @@ import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import net.minecraft.resources.ResourceLocation;
// TODO: add messages to exceptions
-public class MaterialIndices {
+public final class MaterialIndices {
private static Reference2IntMap materialIndices;
private static Object2IntMap vertexShaderIndices;
private static Object2IntMap fragmentShaderIndices;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java b/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java
index 1053a0014..6178eab54 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/material/Materials.java
@@ -1,11 +1,14 @@
package com.jozufozu.flywheel.lib.material;
+import org.jetbrains.annotations.ApiStatus;
+
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.material.Material;
+import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
import com.jozufozu.flywheel.gl.GlTextureUnit;
import com.jozufozu.flywheel.lib.material.SimpleMaterial.GlStateShard;
+import com.jozufozu.flywheel.lib.math.DiffuseLightCalculator;
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
-import com.jozufozu.flywheel.util.DiffuseLightCalculator;
import com.jozufozu.flywheel.util.ResourceUtil;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
@@ -18,7 +21,7 @@ import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.inventory.InventoryMenu;
public final class Materials {
- public static final Material.VertexTransformer SHADING_TRANSFORMER = (vertexList, level) -> {
+ public static final MaterialVertexTransformer SHADING_TRANSFORMER = (vertexList, level) -> {
if (ShadersModHandler.isShaderPackInUse()) {
return;
}
@@ -131,8 +134,8 @@ public final class Materials {
.batchingRenderType(RenderType.entitySolid(MINECART_LOCATION))
.register();
+ @ApiStatus.Internal
public static void init() {
- // noop
}
public static final class Shards {
@@ -173,14 +176,14 @@ public final class Materials {
}
}
- public static class Files {
+ public static final class Files {
public static final ResourceLocation DEFAULT_VERTEX = ResourceUtil.subPath(Names.DEFAULT, ".vert");
public static final ResourceLocation SHADED_VERTEX = ResourceUtil.subPath(Names.SHADED, ".vert");
public static final ResourceLocation DEFAULT_FRAGMENT = ResourceUtil.subPath(Names.DEFAULT, ".frag");
public static final ResourceLocation CUTOUT_FRAGMENT = ResourceUtil.subPath(Names.CUTOUT, ".frag");
}
- public static class Names {
+ public static final class Names {
public static final ResourceLocation DEFAULT = Flywheel.rl("material/default");
public static final ResourceLocation CUTOUT = Flywheel.rl("material/cutout");
public static final ResourceLocation SHADED = Flywheel.rl("material/shaded");
diff --git a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java
index f21a809c2..e25cb070a 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/material/SimpleMaterial.java
@@ -1,6 +1,7 @@
package com.jozufozu.flywheel.lib.material;
import com.jozufozu.flywheel.api.material.Material;
+import com.jozufozu.flywheel.api.material.MaterialVertexTransformer;
import net.minecraft.client.renderer.RenderStateShard;
import net.minecraft.client.renderer.RenderType;
@@ -12,9 +13,9 @@ public class SimpleMaterial implements Material {
protected final Runnable setup;
protected final Runnable clear;
protected final RenderType batchingRenderType;
- protected final VertexTransformer vertexTransformer;
+ protected final MaterialVertexTransformer vertexTransformer;
- public SimpleMaterial(ResourceLocation vertexShader, ResourceLocation fragmentShader, Runnable setup, Runnable clear, RenderType batchingRenderType, VertexTransformer vertexTransformer) {
+ public SimpleMaterial(ResourceLocation vertexShader, ResourceLocation fragmentShader, Runnable setup, Runnable clear, RenderType batchingRenderType, MaterialVertexTransformer vertexTransformer) {
this.vertexShader = vertexShader;
this.fragmentShader = fragmentShader;
this.setup = setup;
@@ -53,7 +54,7 @@ public class SimpleMaterial implements Material {
}
@Override
- public VertexTransformer getVertexTransformer() {
+ public MaterialVertexTransformer getVertexTransformer() {
return vertexTransformer;
}
@@ -63,8 +64,7 @@ public class SimpleMaterial implements Material {
protected Runnable setup = () -> {};
protected Runnable clear = () -> {};
protected RenderType batchingRenderType = RenderType.solid();
- protected VertexTransformer vertexTransformer = (vertexList, level) -> {
- };
+ protected MaterialVertexTransformer vertexTransformer = (vertexList, level) -> {};
public Builder() {
}
@@ -100,7 +100,7 @@ public class SimpleMaterial implements Material {
return this;
}
- public Builder vertexTransformer(VertexTransformer vertexTransformer) {
+ public Builder vertexTransformer(MaterialVertexTransformer vertexTransformer) {
this.vertexTransformer = vertexTransformer;
return this;
}
diff --git a/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java b/src/main/java/com/jozufozu/flywheel/lib/math/DiffuseLightCalculator.java
similarity index 91%
rename from src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java
rename to src/main/java/com/jozufozu/flywheel/lib/math/DiffuseLightCalculator.java
index 2fcf6161e..9ec8414bd 100644
--- a/src/main/java/com/jozufozu/flywheel/util/DiffuseLightCalculator.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/math/DiffuseLightCalculator.java
@@ -1,4 +1,4 @@
-package com.jozufozu.flywheel.util;
+package com.jozufozu.flywheel.lib.math;
import net.minecraft.client.multiplayer.ClientLevel;
diff --git a/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java b/src/main/java/com/jozufozu/flywheel/lib/math/MatrixUtil.java
similarity index 74%
rename from src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java
rename to src/main/java/com/jozufozu/flywheel/lib/math/MatrixUtil.java
index 57b96de79..8a1a25321 100644
--- a/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/math/MatrixUtil.java
@@ -1,4 +1,4 @@
-package com.jozufozu.flywheel.util;
+package com.jozufozu.flywheel.lib.math;
import java.nio.ByteBuffer;
@@ -9,7 +9,37 @@ import com.jozufozu.flywheel.mixin.matrix.Matrix4fAccessor;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
-public class MatrixUtil {
+public final class MatrixUtil {
+ public static float transformPositionX(Matrix4f matrix, float x, float y, float z) {
+ Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
+ return (m.flywheel$m00() * x) + (m.flywheel$m01() * y) + (m.flywheel$m02() * z) + m.flywheel$m03();
+ }
+
+ public static float transformPositionY(Matrix4f matrix, float x, float y, float z) {
+ Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
+ return (m.flywheel$m10() * x) + (m.flywheel$m11() * y) + (m.flywheel$m12() * z) + m.flywheel$m13();
+ }
+
+ public static float transformPositionZ(Matrix4f matrix, float x, float y, float z) {
+ Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
+ return (m.flywheel$m20() * x) + (m.flywheel$m21() * y) + (m.flywheel$m22() * z) + m.flywheel$m23();
+ }
+
+ public static float transformNormalX(Matrix3f matrix, float x, float y, float z) {
+ Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
+ return (m.flywheel$m00() * x) + (m.flywheel$m01() * y) + (m.flywheel$m02() * z);
+ }
+
+ public static float transformNormalY(Matrix3f matrix, float x, float y, float z) {
+ Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
+ return (m.flywheel$m10() * x) + (m.flywheel$m11() * y) + (m.flywheel$m12() * z);
+ }
+
+ public static float transformNormalZ(Matrix3f matrix, float x, float y, float z) {
+ Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
+ return (m.flywheel$m20() * x) + (m.flywheel$m21() * y) + (m.flywheel$m22() * z);
+ }
+
public static void write(Matrix4f matrix, ByteBuffer buf) {
Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
buf.putFloat(m.flywheel$m00());
diff --git a/src/main/java/com/jozufozu/flywheel/lib/math/MoreMath.java b/src/main/java/com/jozufozu/flywheel/lib/math/MoreMath.java
new file mode 100644
index 000000000..b06678d00
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/lib/math/MoreMath.java
@@ -0,0 +1,166 @@
+package com.jozufozu.flywheel.lib.math;
+
+import org.joml.Math;
+import org.joml.Matrix4f;
+import org.lwjgl.system.MemoryUtil;
+
+public final class MoreMath {
+ public static int align16(int numToRound) {
+ return (numToRound + 16 - 1) & -16;
+ }
+
+ public static int numDigits(int number) {
+ // cursed but allegedly the fastest algorithm, taken from https://www.baeldung.com/java-number-of-digits-in-int
+ if (number < 100000) {
+ if (number < 100) {
+ if (number < 10) {
+ return 1;
+ } else {
+ return 2;
+ }
+ } else {
+ if (number < 1000) {
+ return 3;
+ } else {
+ if (number < 10000) {
+ return 4;
+ } else {
+ return 5;
+ }
+ }
+ }
+ } else {
+ if (number < 10000000) {
+ if (number < 1000000) {
+ return 6;
+ } else {
+ return 7;
+ }
+ } else {
+ if (number < 100000000) {
+ return 8;
+ } else {
+ if (number < 1000000000) {
+ return 9;
+ } else {
+ return 10;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Writes the frustum planes of the given projection matrix to the given buffer.
+ * Uses a different format that is friendly towards an optimized instruction-parallel
+ * implementation of sphere-frustum intersection.
+ * The format is as follows:
+ * {@code vec4(nxX, pxX, nyX, pyX)}
+ * {@code vec4(nxY, pxY, nyY, pyY)}
+ * {@code vec4(nxZ, pxZ, nyZ, pyZ)}
+ * {@code vec4(nxW, pxW, nyW, pyW)}
+ * {@code vec2(nzX, pzX)}
+ * {@code vec2(nzY, pzY)}
+ * {@code vec2(nzZ, pzZ)}
+ * {@code vec2(nzW, pzW)}
+ *
+ * Writes 96 bytes to the buffer.
+ *
+ * @param ptr The buffer to write the planes to.
+ * @param m The projection matrix to compute the frustum planes for.
+ */
+ public static void writePackedFrustumPlanes(long ptr, Matrix4f m) {
+ float nxX, nxY, nxZ, nxW;
+ float pxX, pxY, pxZ, pxW;
+ float nyX, nyY, nyZ, nyW;
+ float pyX, pyY, pyZ, pyW;
+ float nzX, nzY, nzZ, nzW;
+ float pzX, pzY, pzZ, pzW;
+
+ float invl;
+ nxX = m.m03() + m.m00();
+ nxY = m.m13() + m.m10();
+ nxZ = m.m23() + m.m20();
+ nxW = m.m33() + m.m30();
+ invl = Math.invsqrt(nxX * nxX + nxY * nxY + nxZ * nxZ);
+ nxX *= invl;
+ nxY *= invl;
+ nxZ *= invl;
+ nxW *= invl;
+
+ pxX = m.m03() - m.m00();
+ pxY = m.m13() - m.m10();
+ pxZ = m.m23() - m.m20();
+ pxW = m.m33() - m.m30();
+ invl = Math.invsqrt(pxX * pxX + pxY * pxY + pxZ * pxZ);
+ pxX *= invl;
+ pxY *= invl;
+ pxZ *= invl;
+ pxW *= invl;
+
+ nyX = m.m03() + m.m01();
+ nyY = m.m13() + m.m11();
+ nyZ = m.m23() + m.m21();
+ nyW = m.m33() + m.m31();
+ invl = Math.invsqrt(nyX * nyX + nyY * nyY + nyZ * nyZ);
+ nyX *= invl;
+ nyY *= invl;
+ nyZ *= invl;
+ nyW *= invl;
+
+ pyX = m.m03() - m.m01();
+ pyY = m.m13() - m.m11();
+ pyZ = m.m23() - m.m21();
+ pyW = m.m33() - m.m31();
+ invl = Math.invsqrt(pyX * pyX + pyY * pyY + pyZ * pyZ);
+ pyX *= invl;
+ pyY *= invl;
+ pyZ *= invl;
+ pyW *= invl;
+
+ nzX = m.m03() + m.m02();
+ nzY = m.m13() + m.m12();
+ nzZ = m.m23() + m.m22();
+ nzW = m.m33() + m.m32();
+ invl = Math.invsqrt(nzX * nzX + nzY * nzY + nzZ * nzZ);
+ nzX *= invl;
+ nzY *= invl;
+ nzZ *= invl;
+ nzW *= invl;
+
+ pzX = m.m03() - m.m02();
+ pzY = m.m13() - m.m12();
+ pzZ = m.m23() - m.m22();
+ pzW = m.m33() - m.m32();
+ invl = Math.invsqrt(pzX * pzX + pzY * pzY + pzZ * pzZ);
+ pzX *= invl;
+ pzY *= invl;
+ pzZ *= invl;
+ pzW *= invl;
+
+ MemoryUtil.memPutFloat(ptr, nxX);
+ MemoryUtil.memPutFloat(ptr + 4, pxX);
+ MemoryUtil.memPutFloat(ptr + 8, nyX);
+ MemoryUtil.memPutFloat(ptr + 12, pyX);
+ MemoryUtil.memPutFloat(ptr + 16, nxY);
+ MemoryUtil.memPutFloat(ptr + 20, pxY);
+ MemoryUtil.memPutFloat(ptr + 24, nyY);
+ MemoryUtil.memPutFloat(ptr + 28, pyY);
+ MemoryUtil.memPutFloat(ptr + 32, nxZ);
+ MemoryUtil.memPutFloat(ptr + 36, pxZ);
+ MemoryUtil.memPutFloat(ptr + 40, nyZ);
+ MemoryUtil.memPutFloat(ptr + 44, pyZ);
+ MemoryUtil.memPutFloat(ptr + 48, nxW);
+ MemoryUtil.memPutFloat(ptr + 52, pxW);
+ MemoryUtil.memPutFloat(ptr + 56, nyW);
+ MemoryUtil.memPutFloat(ptr + 60, pyW);
+ MemoryUtil.memPutFloat(ptr + 64, nzX);
+ MemoryUtil.memPutFloat(ptr + 68, pzX);
+ MemoryUtil.memPutFloat(ptr + 72, nzY);
+ MemoryUtil.memPutFloat(ptr + 76, pzY);
+ MemoryUtil.memPutFloat(ptr + 80, nzZ);
+ MemoryUtil.memPutFloat(ptr + 84, pzZ);
+ MemoryUtil.memPutFloat(ptr + 88, nzW);
+ MemoryUtil.memPutFloat(ptr + 92, pzW);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/RenderMath.java b/src/main/java/com/jozufozu/flywheel/lib/math/RenderMath.java
similarity index 95%
rename from src/main/java/com/jozufozu/flywheel/util/RenderMath.java
rename to src/main/java/com/jozufozu/flywheel/lib/math/RenderMath.java
index 213cc2819..d7d015161 100644
--- a/src/main/java/com/jozufozu/flywheel/util/RenderMath.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/math/RenderMath.java
@@ -1,9 +1,8 @@
-package com.jozufozu.flywheel.util;
+package com.jozufozu.flywheel.lib.math;
import net.minecraftforge.client.model.pipeline.LightUtil;
-public class RenderMath {
-
+public final class RenderMath {
/**
* Convert a signed byte into a signed, normalized float.
*/
diff --git a/src/main/java/com/jozufozu/flywheel/lib/memory/FlwMemoryTracker.java b/src/main/java/com/jozufozu/flywheel/lib/memory/FlwMemoryTracker.java
index c66e852a9..6aec1b3e3 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/memory/FlwMemoryTracker.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/memory/FlwMemoryTracker.java
@@ -7,7 +7,7 @@ import org.lwjgl.system.MemoryUtil;
import com.jozufozu.flywheel.util.StringUtil;
-public class FlwMemoryTracker {
+public final class FlwMemoryTracker {
public static final boolean DEBUG_MEMORY_SAFETY = System.getProperty("flw.debugMemorySafety") != null;
static final Cleaner CLEANER = Cleaner.create();
diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/ModelUtil.java b/src/main/java/com/jozufozu/flywheel/lib/model/ModelUtil.java
index 654d5ef9f..aa930bbda 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/model/ModelUtil.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/model/ModelUtil.java
@@ -6,21 +6,21 @@ import java.nio.ByteBuffer;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector4f;
import org.lwjgl.system.MemoryUtil;
+import org.slf4j.Logger;
import com.dreizak.miniball.highdim.Miniball;
import com.dreizak.miniball.model.PointSet;
-import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.api.vertex.VertexList;
import com.jozufozu.flywheel.api.vertex.VertexListProviderRegistry;
import com.jozufozu.flywheel.api.vertex.VertexType;
-import com.jozufozu.flywheel.lib.format.Formats;
import com.jozufozu.flywheel.lib.material.Materials;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
import com.mojang.blaze3d.vertex.BufferBuilder.DrawState;
import com.mojang.blaze3d.vertex.VertexFormat;
import com.mojang.datafixers.util.Pair;
+import com.mojang.logging.LogUtils;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderType;
@@ -28,7 +28,9 @@ import net.minecraft.client.renderer.block.BlockRenderDispatcher;
import net.minecraft.client.renderer.block.ModelBlockRenderer;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
-public class ModelUtil {
+public final class ModelUtil {
+ private static final Logger LOGGER = LogUtils.getLogger();
+
/**
* An alternative BlockRenderDispatcher that circumvents the Forge rendering pipeline to ensure consistency.
* Meant to be used for virtual rendering.
@@ -45,25 +47,24 @@ public class ModelUtil {
}
ObfuscationReflectionHelper.setPrivateValue(BlockRenderDispatcher.class, dispatcher, new ModelBlockRenderer(Minecraft.getInstance().getBlockColors()), "f_110900_");
} catch (Exception e) {
- Flywheel.LOGGER.error("Failed to initialize vanilla BlockRenderDispatcher!", e);
+ LOGGER.error("Failed to initialize vanilla BlockRenderDispatcher!", e);
return defaultDispatcher;
}
return dispatcher;
}
- public static Pair convertBlockBuffer(Pair pair) {
+ public static MemoryBlock convertVanillaBuffer(Pair pair, VertexType vertexType) {
DrawState drawState = pair.getFirst();
int vertexCount = drawState.vertexCount();
VertexFormat srcFormat = drawState.format();
- VertexType dstVertexType = Formats.BLOCK;
ByteBuffer src = pair.getSecond();
- MemoryBlock dst = MemoryBlock.malloc(vertexCount * dstVertexType.getLayout().getStride());
+ MemoryBlock dst = MemoryBlock.malloc(vertexCount * vertexType.getLayout().getStride());
long srcPtr = MemoryUtil.memAddress(src);
long dstPtr = dst.ptr();
ReusableVertexList srcList = VertexListProviderRegistry.getProvider(srcFormat).createVertexList();
- ReusableVertexList dstList = dstVertexType.createVertexList();
+ ReusableVertexList dstList = vertexType.createVertexList();
srcList.ptr(srcPtr);
dstList.ptr(dstPtr);
srcList.vertexCount(vertexCount);
@@ -71,7 +72,7 @@ public class ModelUtil {
srcList.writeAll(dstList);
- return Pair.of(dstVertexType, dst);
+ return dst;
}
@Nullable
diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/Models.java b/src/main/java/com/jozufozu/flywheel/lib/model/Models.java
index 8caf445e8..fe55c0147 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/model/Models.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/model/Models.java
@@ -15,7 +15,7 @@ import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.core.Direction;
import net.minecraft.world.level.block.state.BlockState;
-public class Models {
+public final class Models {
private static final Map BLOCK_STATE = new HashMap<>();
private static final Map PARTIAL = new HashMap<>();
private static final Map, Model> PARTIAL_DIR = new HashMap<>();
diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/QuadMesh.java b/src/main/java/com/jozufozu/flywheel/lib/model/QuadMesh.java
new file mode 100644
index 000000000..2c46b040f
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/lib/model/QuadMesh.java
@@ -0,0 +1,23 @@
+package com.jozufozu.flywheel.lib.model;
+
+import com.jozufozu.flywheel.api.model.Mesh;
+import com.jozufozu.flywheel.gl.buffer.ElementBuffer;
+import com.jozufozu.flywheel.lib.util.QuadConverter;
+
+public interface QuadMesh extends Mesh {
+ /**
+ * Create an element buffer object that indexes the vertices of this mesh.
+ *
+ *
+ * Very often models in minecraft are made up of sequential quads, which is a very predictable pattern.
+ * The default implementation accommodates this, however this can be overridden to change the behavior and
+ * support more complex models.
+ *
+ * @return an element buffer object indexing this model's vertices.
+ */
+ @Override
+ default ElementBuffer createEBO() {
+ return QuadConverter.getInstance()
+ .quads2Tris(getVertexCount() / 4);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/SimpleMesh.java b/src/main/java/com/jozufozu/flywheel/lib/model/SimpleMesh.java
index 7d4724d63..197b6ee7f 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/model/SimpleMesh.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/model/SimpleMesh.java
@@ -3,13 +3,12 @@ package com.jozufozu.flywheel.lib.model;
import org.joml.Vector4f;
import org.joml.Vector4fc;
-import com.jozufozu.flywheel.api.model.Mesh;
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.api.vertex.VertexType;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
-public class SimpleMesh implements Mesh {
+public class SimpleMesh implements QuadMesh {
private final VertexType vertexType;
private final int vertexCount;
private final MemoryBlock contents;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/buffering/BakedModelBuilder.java b/src/main/java/com/jozufozu/flywheel/lib/model/buffering/BakedModelBuilder.java
index 48b99319a..cfc6640fb 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/model/buffering/BakedModelBuilder.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/model/buffering/BakedModelBuilder.java
@@ -5,7 +5,7 @@ import java.util.function.BiFunction;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.model.Mesh;
-import com.jozufozu.flywheel.api.vertex.VertexType;
+import com.jozufozu.flywheel.lib.format.Formats;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
import com.jozufozu.flywheel.lib.model.ModelUtil;
import com.jozufozu.flywheel.lib.model.SimpleMesh;
@@ -20,7 +20,6 @@ import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexFormat;
-import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.resources.model.BakedModel;
@@ -106,8 +105,8 @@ public class BakedModelBuilder {
buffer.end();
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
- Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
- meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded));
+ MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
+ meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded));
}
};
ModelBufferingUtil.bufferSingleShadeSeparated(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer);
@@ -121,8 +120,8 @@ public class BakedModelBuilder {
buffer.end();
Material material = materialFunc.apply(renderType, false);
if (material != null) {
- Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
- meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString()));
+ MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
+ meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString()));
}
};
ModelBufferingUtil.bufferSingle(ModelUtil.VANILLA_RENDERER.getModelRenderer(), renderWorld, bakedModel, blockState, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelData, resultConsumer);
diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/buffering/BlockModelBuilder.java b/src/main/java/com/jozufozu/flywheel/lib/model/buffering/BlockModelBuilder.java
index dd4a54dc1..e5372f7d3 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/model/buffering/BlockModelBuilder.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/model/buffering/BlockModelBuilder.java
@@ -5,7 +5,7 @@ import java.util.function.BiFunction;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.model.Mesh;
-import com.jozufozu.flywheel.api.vertex.VertexType;
+import com.jozufozu.flywheel.lib.format.Formats;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
import com.jozufozu.flywheel.lib.model.ModelUtil;
import com.jozufozu.flywheel.lib.model.SimpleMesh;
@@ -20,7 +20,6 @@ import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexFormat;
-import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.world.level.BlockAndTintGetter;
@@ -95,8 +94,8 @@ public class BlockModelBuilder {
buffer.end();
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
- Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
- meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "state=" + state.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded));
+ MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
+ meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "state=" + state.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded));
}
};
ModelBufferingUtil.bufferBlockShadeSeparated(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelData, resultConsumer);
@@ -110,8 +109,8 @@ public class BlockModelBuilder {
buffer.end();
Material material = materialFunc.apply(renderType, false);
if (material != null) {
- Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
- meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "state=" + state.toString() + ",renderType=" + renderType.toString()));
+ MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
+ meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "state=" + state.toString() + ",renderType=" + renderType.toString()));
}
};
ModelBufferingUtil.bufferBlock(ModelUtil.VANILLA_RENDERER, renderWorld, state, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelData, resultConsumer);
diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/buffering/MultiBlockModelBuilder.java b/src/main/java/com/jozufozu/flywheel/lib/model/buffering/MultiBlockModelBuilder.java
index 6f0581624..888e07405 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/model/buffering/MultiBlockModelBuilder.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/model/buffering/MultiBlockModelBuilder.java
@@ -8,7 +8,7 @@ import java.util.function.BiFunction;
import com.google.common.collect.ImmutableMap;
import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.model.Mesh;
-import com.jozufozu.flywheel.api.vertex.VertexType;
+import com.jozufozu.flywheel.lib.format.Formats;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
import com.jozufozu.flywheel.lib.model.ModelUtil;
import com.jozufozu.flywheel.lib.model.SimpleMesh;
@@ -22,7 +22,6 @@ import com.mojang.blaze3d.vertex.BufferBuilder;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexFormat;
-import com.mojang.datafixers.util.Pair;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.BlockPos;
@@ -102,8 +101,8 @@ public class MultiBlockModelBuilder {
buffer.end();
Material material = materialFunc.apply(renderType, shaded);
if (material != null) {
- Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
- meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "renderType=" + renderType.toString() + ",shaded=" + shaded));
+ MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
+ meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "renderType=" + renderType.toString() + ",shaded=" + shaded));
}
};
ModelBufferingUtil.bufferMultiBlockShadeSeparated(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelDataMap, resultConsumer);
@@ -117,8 +116,8 @@ public class MultiBlockModelBuilder {
buffer.end();
Material material = materialFunc.apply(renderType, false);
if (material != null) {
- Pair pair = ModelUtil.convertBlockBuffer(buffer.popNextBuffer());
- meshMapBuilder.put(material, new SimpleMesh(pair.getFirst(), pair.getSecond(), "renderType=" + renderType.toString()));
+ MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK);
+ meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "renderType=" + renderType.toString()));
}
};
ModelBufferingUtil.bufferMultiBlock(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.bufferWrapper, objects.random, modelDataMap, resultConsumer);
diff --git a/src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPart.java b/src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPart.java
index dfadcc10a..7a56cef2d 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPart.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPart.java
@@ -5,22 +5,22 @@ import java.util.List;
import org.joml.Vector4f;
import org.joml.Vector4fc;
-import com.jozufozu.flywheel.api.model.Mesh;
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
import com.jozufozu.flywheel.lib.format.Formats;
import com.jozufozu.flywheel.lib.format.PosTexNormalVertex;
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
import com.jozufozu.flywheel.lib.model.ModelUtil;
+import com.jozufozu.flywheel.lib.model.QuadMesh;
-public class ModelPart implements Mesh {
+public class ModelPart implements QuadMesh {
private final int vertexCount;
private final MemoryBlock contents;
private final ReusableVertexList vertexList;
private final Vector4f boundingSphere;
private final String name;
- public ModelPart(List cuboids, String name) {
+ public ModelPart(List cuboids, String name) {
this.name = name;
this.vertexCount = countVertices(cuboids);
@@ -28,7 +28,7 @@ public class ModelPart implements Mesh {
contents = MemoryBlock.malloc(size());
long ptr = contents.ptr();
VertexWriter writer = new VertexWriterImpl(ptr);
- for (PartBuilder.CuboidBuilder cuboid : cuboids) {
+ for (ModelPartBuilder.CuboidBuilder cuboid : cuboids) {
cuboid.write(writer);
}
@@ -39,8 +39,8 @@ public class ModelPart implements Mesh {
boundingSphere = ModelUtil.computeBoundingSphere(vertexList);
}
- public static PartBuilder builder(String name, int sizeU, int sizeV) {
- return new PartBuilder(name, sizeU, sizeV);
+ public static ModelPartBuilder builder(String name, int sizeU, int sizeV) {
+ return new ModelPartBuilder(name, sizeU, sizeV);
}
@Override
@@ -78,9 +78,9 @@ public class ModelPart implements Mesh {
return name;
}
- private static int countVertices(List cuboids) {
+ private static int countVertices(List cuboids) {
int vertices = 0;
- for (PartBuilder.CuboidBuilder cuboid : cuboids) {
+ for (ModelPartBuilder.CuboidBuilder cuboid : cuboids) {
vertices += cuboid.vertices();
}
return vertices;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/modelpart/PartBuilder.java b/src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPartBuilder.java
similarity index 89%
rename from src/main/java/com/jozufozu/flywheel/lib/modelpart/PartBuilder.java
rename to src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPartBuilder.java
index f3b4d6200..84f8aa830 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/modelpart/PartBuilder.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPartBuilder.java
@@ -12,8 +12,7 @@ import com.mojang.math.Vector3f;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.core.Direction;
-public class PartBuilder {
-
+public class ModelPartBuilder {
private final float sizeU;
private final float sizeV;
@@ -22,13 +21,13 @@ public class PartBuilder {
private final List cuboids = new ArrayList<>();
private final String name;
- public PartBuilder(String name, int sizeU, int sizeV) {
+ public ModelPartBuilder(String name, int sizeU, int sizeV) {
this.name = name;
this.sizeU = (float) sizeU;
this.sizeV = (float) sizeV;
}
- public PartBuilder sprite(TextureAtlasSprite sprite) {
+ public ModelPartBuilder sprite(TextureAtlasSprite sprite) {
this.sprite = sprite;
return this;
}
@@ -41,36 +40,35 @@ public class PartBuilder {
return new ModelPart(cuboids, name);
}
- private PartBuilder addCuboid(CuboidBuilder builder) {
+ private ModelPartBuilder addCuboid(CuboidBuilder builder) {
cuboids.add(builder);
return this;
}
public static class CuboidBuilder {
+ private TextureAtlasSprite sprite;
- TextureAtlasSprite sprite;
+ private Set visibleFaces = EnumSet.allOf(Direction.class);
+ private int textureOffsetU;
+ private int textureOffsetV;
- Set visibleFaces = EnumSet.allOf(Direction.class);
- int textureOffsetU;
- int textureOffsetV;
+ private float posX1;
+ private float posY1;
+ private float posZ1;
+ private float posX2;
+ private float posY2;
+ private float posZ2;
- float posX1;
- float posY1;
- float posZ1;
- float posX2;
- float posY2;
- float posZ2;
+ private boolean invertYZ;
- boolean invertYZ;
+ private boolean useRotation;
+ private float rotationX;
+ private float rotationY;
+ private float rotationZ;
- boolean useRotation;
- float rotationX;
- float rotationY;
- float rotationZ;
+ private final ModelPartBuilder partBuilder;
- final PartBuilder partBuilder;
-
- CuboidBuilder(PartBuilder partBuilder) {
+ private CuboidBuilder(ModelPartBuilder partBuilder) {
this.partBuilder = partBuilder;
this.sprite = partBuilder.sprite;
}
@@ -151,7 +149,7 @@ public class PartBuilder {
return this;
}
- public PartBuilder endCuboid() {
+ public ModelPartBuilder endCuboid() {
return partBuilder.addCuboid(this);
}
@@ -254,5 +252,4 @@ public class PartBuilder {
return v / partBuilder.sizeV;
}
}
-
}
diff --git a/src/main/java/com/jozufozu/flywheel/lib/modelpart/VertexWriterImpl.java b/src/main/java/com/jozufozu/flywheel/lib/modelpart/VertexWriterImpl.java
index 53fb8ee96..125e7526b 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/modelpart/VertexWriterImpl.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/modelpart/VertexWriterImpl.java
@@ -2,7 +2,7 @@ package com.jozufozu.flywheel.lib.modelpart;
import org.lwjgl.system.MemoryUtil;
-import com.jozufozu.flywheel.util.RenderMath;
+import com.jozufozu.flywheel.lib.math.RenderMath;
public class VertexWriterImpl implements VertexWriter {
private long ptr;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/AbstractInstancePart.java b/src/main/java/com/jozufozu/flywheel/lib/struct/AbstractInstancePart.java
index 71b55fc4d..fde6ab5b5 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/struct/AbstractInstancePart.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/struct/AbstractInstancePart.java
@@ -1,12 +1,11 @@
package com.jozufozu.flywheel.lib.struct;
-import com.jozufozu.flywheel.api.instancer.Handle;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
+import com.jozufozu.flywheel.api.struct.Handle;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.api.struct.StructType;
public abstract class AbstractInstancePart implements InstancePart {
-
- public final StructType> type;
+ protected final StructType> type;
protected final Handle handle;
protected AbstractInstancePart(StructType> type, Handle handle) {
diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitPart.java b/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitPart.java
index a6339f577..b92815f7e 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitPart.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitPart.java
@@ -1,12 +1,11 @@
package com.jozufozu.flywheel.lib.struct;
-import com.jozufozu.flywheel.api.instancer.Handle;
+import com.jozufozu.flywheel.api.struct.Handle;
import com.jozufozu.flywheel.api.struct.StructType;
import net.minecraft.client.renderer.LightTexture;
public abstract class ColoredLitPart extends AbstractInstancePart implements FlatLit {
-
public byte blockLight;
public byte skyLight;
@@ -15,7 +14,7 @@ public abstract class ColoredLitPart extends AbstractInstancePart implements Fla
public byte b = (byte) 0xFF;
public byte a = (byte) 0xFF;
- public ColoredLitPart(StructType> type, Handle handle) {
+ public ColoredLitPart(StructType extends ColoredLitPart> type, Handle handle) {
super(type, handle);
}
@@ -35,7 +34,7 @@ public abstract class ColoredLitPart extends AbstractInstancePart implements Fla
@Override
public int getPackedLight() {
- return LightTexture.pack(this.blockLight, this.skyLight);
+ return LightTexture.pack(blockLight, skyLight);
}
public ColoredLitPart setColor(int color) {
diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/FlatLit.java b/src/main/java/com/jozufozu/flywheel/lib/struct/FlatLit.java
index 19d95bcf5..ae23de706 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/struct/FlatLit.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/struct/FlatLit.java
@@ -1,6 +1,6 @@
package com.jozufozu.flywheel.lib.struct;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import net.minecraft.core.BlockPos;
import net.minecraft.world.level.BlockAndTintGetter;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedPart.java b/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedPart.java
index 2f00ab4f2..c8589fd3b 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedPart.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedPart.java
@@ -1,13 +1,13 @@
package com.jozufozu.flywheel.lib.struct;
-import com.jozufozu.flywheel.api.instancer.Handle;
+import com.jozufozu.flywheel.api.struct.Handle;
+import com.jozufozu.flywheel.api.struct.StructType;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
import net.minecraft.core.BlockPos;
public class OrientedPart extends ColoredLitPart {
-
public float posX;
public float posY;
public float posZ;
@@ -19,8 +19,8 @@ public class OrientedPart extends ColoredLitPart {
public float qZ;
public float qW = 1;
- public OrientedPart(Handle handle) {
- super(StructTypes.ORIENTED, handle);
+ public OrientedPart(StructType extends OrientedPart> type, Handle handle) {
+ super(type, handle);
}
public OrientedPart setPosition(BlockPos pos) {
@@ -87,7 +87,7 @@ public class OrientedPart extends ColoredLitPart {
@Override
public OrientedPart copy(Handle handle) {
- var out = new OrientedPart(handle);
+ var out = StructTypes.ORIENTED.create(handle);
out.posX = this.posX;
out.posY = this.posY;
out.posZ = this.posZ;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedType.java b/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedType.java
index 6185819d6..ae0317fbd 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedType.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedType.java
@@ -1,21 +1,20 @@
package com.jozufozu.flywheel.lib.struct;
-import com.jozufozu.flywheel.api.instancer.Handle;
import com.jozufozu.flywheel.api.layout.BufferLayout;
+import com.jozufozu.flywheel.api.struct.Handle;
import com.jozufozu.flywheel.api.struct.StructType;
+import com.jozufozu.flywheel.api.struct.StructVertexTransformer;
import com.jozufozu.flywheel.api.struct.StructWriter;
import com.jozufozu.flywheel.lib.layout.CommonItems;
-import com.jozufozu.flywheel.util.RenderMath;
+import com.jozufozu.flywheel.lib.math.RenderMath;
+import com.jozufozu.flywheel.lib.vertex.VertexTransformations;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
import com.mojang.math.Quaternion;
-import com.mojang.math.Vector3f;
-import com.mojang.math.Vector4f;
import net.minecraft.resources.ResourceLocation;
public class OrientedType implements StructType {
-
public static final BufferLayout FORMAT = BufferLayout.builder()
.addItem(CommonItems.LIGHT_COORD, "light")
.addItem(CommonItems.UNORM_4x8, "color")
@@ -26,7 +25,7 @@ public class OrientedType implements StructType {
@Override
public OrientedPart create(Handle handle) {
- return new OrientedPart(handle);
+ return new OrientedPart(this, handle);
}
@Override
@@ -45,11 +44,8 @@ public class OrientedType implements StructType {
}
@Override
- public VertexTransformer getVertexTransformer() {
+ public StructVertexTransformer getVertexTransformer() {
return (vertexList, struct, level) -> {
- Vector4f pos = new Vector4f();
- Vector3f normal = new Vector3f();
-
Quaternion q = new Quaternion(struct.qX, struct.qY, struct.qZ, struct.qW);
Matrix4f modelMatrix = new Matrix4f();
@@ -67,27 +63,8 @@ public class OrientedType implements StructType {
int light = struct.getPackedLight();
for (int i = 0; i < vertexList.vertexCount(); i++) {
- pos.set(
- vertexList.x(i),
- vertexList.y(i),
- vertexList.z(i),
- 1f
- );
- pos.transform(modelMatrix);
- vertexList.x(i, pos.x());
- vertexList.y(i, pos.y());
- vertexList.z(i, pos.z());
-
- normal.set(
- vertexList.normalX(i),
- vertexList.normalY(i),
- vertexList.normalZ(i)
- );
- normal.transform(normalMatrix);
- normal.normalize();
- vertexList.normalX(i, normal.x());
- vertexList.normalY(i, normal.y());
- vertexList.normalZ(i, normal.z());
+ VertexTransformations.transformPos(vertexList, i, modelMatrix);
+ VertexTransformations.transformNormal(vertexList, i, normalMatrix);
vertexList.r(i, r);
vertexList.g(i, g);
diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/StructTypes.java b/src/main/java/com/jozufozu/flywheel/lib/struct/StructTypes.java
index fddeb37c9..f42b02b9f 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/struct/StructTypes.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/struct/StructTypes.java
@@ -1,25 +1,27 @@
package com.jozufozu.flywheel.lib.struct;
+import org.jetbrains.annotations.ApiStatus;
+
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
-public class StructTypes {
+public final class StructTypes {
public static final StructType TRANSFORMED = StructType.REGISTRY.registerAndGet(new TransformedType());
public static final StructType ORIENTED = StructType.REGISTRY.registerAndGet(new OrientedType());
+ @ApiStatus.Internal
public static void init() {
- // noop
}
- public static class Files {
+ public static final class Files {
public static final ResourceLocation TRANSFORMED = ResourceUtil.subPath(Names.TRANSFORMED, ".vert");
public static final ResourceLocation ORIENTED = ResourceUtil.subPath(Names.ORIENTED, ".vert");
}
- public static class Names {
+ public static final class Names {
public static final ResourceLocation TRANSFORMED = Flywheel.rl("instance/transformed");
public static final ResourceLocation ORIENTED = Flywheel.rl("instance/oriented");
}
diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedPart.java b/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedPart.java
index 16a19233d..90f1bb519 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedPart.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedPart.java
@@ -1,6 +1,7 @@
package com.jozufozu.flywheel.lib.struct;
-import com.jozufozu.flywheel.api.instancer.Handle;
+import com.jozufozu.flywheel.api.struct.Handle;
+import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.lib.transform.Transform;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix3f;
@@ -16,8 +17,8 @@ public class TransformedPart extends ColoredLitPart implements Transform type, Handle handle) {
+ super(type, handle);
}
public TransformedPart setTransform(PoseStack stack) {
@@ -106,7 +107,7 @@ public class TransformedPart extends ColoredLitPart implements Transform {
-
public static final BufferLayout FORMAT = BufferLayout.builder()
.addItem(CommonItems.LIGHT_COORD, "light")
.addItem(CommonItems.UNORM_4x8, "color")
@@ -22,7 +21,7 @@ public class TransformedType implements StructType {
@Override
public TransformedPart create(Handle handle) {
- return new TransformedPart(handle);
+ return new TransformedPart(this, handle);
}
@Override
@@ -41,11 +40,8 @@ public class TransformedType implements StructType {
}
@Override
- public VertexTransformer getVertexTransformer() {
+ public StructVertexTransformer getVertexTransformer() {
return (vertexList, struct, level) -> {
- Vector4f pos = new Vector4f();
- Vector3f normal = new Vector3f();
-
float r = RenderMath.uf(struct.r);
float g = RenderMath.uf(struct.g);
float b = RenderMath.uf(struct.b);
@@ -53,27 +49,8 @@ public class TransformedType implements StructType {
int light = struct.getPackedLight();
for (int i = 0; i < vertexList.vertexCount(); i++) {
- pos.set(
- vertexList.x(i),
- vertexList.y(i),
- vertexList.z(i),
- 1f
- );
- pos.transform(struct.model);
- vertexList.x(i, pos.x());
- vertexList.y(i, pos.y());
- vertexList.z(i, pos.z());
-
- normal.set(
- vertexList.normalX(i),
- vertexList.normalY(i),
- vertexList.normalZ(i)
- );
- normal.transform(struct.normal);
- normal.normalize();
- vertexList.normalX(i, normal.x());
- vertexList.normalY(i, normal.y());
- vertexList.normalZ(i, normal.z());
+ VertexTransformations.transformPos(vertexList, i, struct.model);
+ VertexTransformations.transformNormal(vertexList, i, struct.normal);
vertexList.r(i, r);
vertexList.g(i, g);
diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedWriter.java b/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedWriter.java
index bb69dcb6c..e18d14f9c 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedWriter.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedWriter.java
@@ -1,6 +1,6 @@
package com.jozufozu.flywheel.lib.struct;
-import com.jozufozu.flywheel.util.MatrixUtil;
+import com.jozufozu.flywheel.lib.math.MatrixUtil;
public class TransformedWriter extends ColoredLitWriter {
public static final TransformedWriter INSTANCE = new TransformedWriter();
diff --git a/src/main/java/com/jozufozu/flywheel/lib/task/WorkGroup.java b/src/main/java/com/jozufozu/flywheel/lib/task/WorkGroup.java
index 82dee6bee..8de35d7b5 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/task/WorkGroup.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/task/WorkGroup.java
@@ -8,7 +8,7 @@ import java.util.stream.Stream;
import org.jetbrains.annotations.Nullable;
-public class WorkGroup {
+public final class WorkGroup {
public static void run(Iterator tasks, Executor executor) {
tasks.forEachRemaining(executor::execute);
}
diff --git a/src/main/java/com/jozufozu/flywheel/lib/uniform/FlwShaderUniforms.java b/src/main/java/com/jozufozu/flywheel/lib/uniform/FlwShaderUniforms.java
index a967fadfb..4f88499ac 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/uniform/FlwShaderUniforms.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/uniform/FlwShaderUniforms.java
@@ -9,8 +9,8 @@ import com.jozufozu.flywheel.api.event.BeginFrameEvent;
import com.jozufozu.flywheel.api.event.RenderContext;
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
-import com.jozufozu.flywheel.util.FlwUtil;
-import com.jozufozu.flywheel.util.MatrixUtil;
+import com.jozufozu.flywheel.lib.math.MatrixUtil;
+import com.jozufozu.flywheel.lib.math.MoreMath;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.core.Vec3i;
@@ -134,7 +134,7 @@ public class FlwShaderUniforms implements ShaderUniforms {
var projection = MatrixUtil.toJoml(context.viewProjection());
projection.translate(-camX, -camY, -camZ);
- FlwUtil.writePackedFrustumPlanes(ptr + 128, projection);
+ MoreMath.writePackedFrustumPlanes(ptr + 128, projection);
FRUSTUM_CAPTURE = false;
}
diff --git a/src/main/java/com/jozufozu/flywheel/util/AnimationTickHolder.java b/src/main/java/com/jozufozu/flywheel/lib/util/AnimationTickHolder.java
similarity index 93%
rename from src/main/java/com/jozufozu/flywheel/util/AnimationTickHolder.java
rename to src/main/java/com/jozufozu/flywheel/lib/util/AnimationTickHolder.java
index 20ed918df..3c2fbaff6 100644
--- a/src/main/java/com/jozufozu/flywheel/util/AnimationTickHolder.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/util/AnimationTickHolder.java
@@ -1,4 +1,4 @@
-package com.jozufozu.flywheel.util;
+package com.jozufozu.flywheel.lib.util;
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
@@ -7,8 +7,7 @@ import net.minecraft.client.Minecraft;
/**
* Static access to tick-count and partialTick time, accounting for pausing.
*/
-public class AnimationTickHolder {
-
+public final class AnimationTickHolder {
// Wrap around every 24 hours to maintain floating point accuracy.
private static final int wrappingInterval = 1_728_000;
private static int ticks;
diff --git a/src/main/java/com/jozufozu/flywheel/lib/util/QuadConverter.java b/src/main/java/com/jozufozu/flywheel/lib/util/QuadConverter.java
index 95ec577e9..3dd415bf8 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/util/QuadConverter.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/util/QuadConverter.java
@@ -20,7 +20,6 @@ import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
* A class to manage EBOs that index quads as triangles.
*/
public class QuadConverter {
-
private static QuadConverter INSTANCE;
@NotNull
diff --git a/src/main/java/com/jozufozu/flywheel/lib/util/ShadersModHandler.java b/src/main/java/com/jozufozu/flywheel/lib/util/ShadersModHandler.java
index 0d4546980..9b1435663 100644
--- a/src/main/java/com/jozufozu/flywheel/lib/util/ShadersModHandler.java
+++ b/src/main/java/com/jozufozu/flywheel/lib/util/ShadersModHandler.java
@@ -6,6 +6,7 @@ import java.util.function.BooleanSupplier;
import javax.annotation.Nullable;
+import org.jetbrains.annotations.ApiStatus;
import org.slf4j.Logger;
import com.mojang.logging.LogUtils;
@@ -19,53 +20,53 @@ public final class ShadersModHandler {
private static final Logger LOGGER = LogUtils.getLogger();
public static final String OPTIFINE_ROOT_PACKAGE = "net.optifine";
- public static final String SHADER_PACKAGE = "net.optifine.shaders";
+ public static final String OPTIFINE_SHADER_PACKAGE = "net.optifine.shaders";
- private static final boolean isOculusLoaded;
- private static final boolean isOptifineInstalled;
- private static final InternalHandler internalHandler;
+ private static final boolean IS_OCULUS_LOADED;
+ private static final boolean IS_OPTIFINE_INSTALLED;
+ private static final InternalHandler INTERNAL_HANDLER;
static {
Package optifinePackage = Package.getPackage(OPTIFINE_ROOT_PACKAGE);
- isOptifineInstalled = optifinePackage != null;
- isOculusLoaded = ModList.get()
+ IS_OPTIFINE_INSTALLED = optifinePackage != null;
+ IS_OCULUS_LOADED = ModList.get()
.isLoaded("oculus");
// optfine and oculus are assumed to be mutually exclusive
- if (isOptifineInstalled) {
+ if (IS_OPTIFINE_INSTALLED) {
LOGGER.info("Optifine detected.");
- internalHandler = new Optifine();
- } else if (isOculusLoaded) {
+ INTERNAL_HANDLER = new Optifine();
+ } else if (IS_OCULUS_LOADED) {
LOGGER.info("Oculus detected.");
- internalHandler = new Oculus();
+ INTERNAL_HANDLER = new Oculus();
} else {
LOGGER.info("No shaders mod detected.");
- internalHandler = new InternalHandler() {};
+ INTERNAL_HANDLER = new InternalHandler() {};
}
}
- private ShadersModHandler() {
- }
-
- public static void init() {
- // noop, load statics
+ public static boolean isOculusLoaded() {
+ return IS_OCULUS_LOADED;
}
public static boolean isOptifineInstalled() {
- return isOptifineInstalled;
- }
-
- public static boolean isOculusLoaded() {
- return isOculusLoaded;
+ return IS_OPTIFINE_INSTALLED;
}
public static boolean isShaderPackInUse() {
- return internalHandler.isShaderPackInUse();
+ return INTERNAL_HANDLER.isShaderPackInUse();
}
public static boolean isRenderingShadowPass() {
- return internalHandler.isRenderingShadowPass();
+ return INTERNAL_HANDLER.isRenderingShadowPass();
+ }
+
+ @ApiStatus.Internal
+ public static void init() {
+ }
+
+ private ShadersModHandler() {
}
private interface InternalHandler {
diff --git a/src/main/java/com/jozufozu/flywheel/lib/vertex/VertexTransformations.java b/src/main/java/com/jozufozu/flywheel/lib/vertex/VertexTransformations.java
new file mode 100644
index 000000000..4e37aff40
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/lib/vertex/VertexTransformations.java
@@ -0,0 +1,36 @@
+package com.jozufozu.flywheel.lib.vertex;
+
+import com.jozufozu.flywheel.api.vertex.MutableVertexList;
+import com.jozufozu.flywheel.lib.math.MatrixUtil;
+import com.mojang.math.Matrix3f;
+import com.mojang.math.Matrix4f;
+
+public final class VertexTransformations {
+ public static void transformPos(MutableVertexList vertexList, int index, Matrix4f matrix) {
+ float x = vertexList.x(index);
+ float y = vertexList.y(index);
+ float z = vertexList.z(index);
+ vertexList.x(index, MatrixUtil.transformPositionX(matrix, x, y, z));
+ vertexList.y(index, MatrixUtil.transformPositionY(matrix, x, y, z));
+ vertexList.z(index, MatrixUtil.transformPositionZ(matrix, x, y, z));
+ }
+
+ public static void transformNormal(MutableVertexList vertexList, int index, Matrix3f matrix) {
+ float nx = vertexList.normalX(index);
+ float ny = vertexList.normalY(index);
+ float nz = vertexList.normalZ(index);
+ float tnx = MatrixUtil.transformNormalX(matrix, nx, ny, nz);
+ float tny = MatrixUtil.transformNormalY(matrix, nx, ny, nz);
+ float tnz = MatrixUtil.transformNormalZ(matrix, nx, ny, nz);
+ float sqrLength = tnx * tnx + tny * tny + tnz * tnz;
+ if (sqrLength != 0) {
+ float f = 1 / (float) Math.sqrt(sqrLength);
+ tnx *= f;
+ tny *= f;
+ tnz *= f;
+ }
+ vertexList.normalX(index, tnx);
+ vertexList.normalY(index, tny);
+ vertexList.normalZ(index, tnz);
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java
index 0740b96f0..5e459f9f1 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java
@@ -9,9 +9,9 @@ import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.google.common.collect.Lists;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.extension.ClientLevelExtension;
import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper;
+import com.jozufozu.flywheel.util.FlwUtil;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.entity.Entity;
@@ -29,7 +29,7 @@ public abstract class ClientLevelMixin implements ClientLevelExtension {
@Inject(method = "entitiesForRendering", at = @At("RETURN"), cancellable = true)
private void flywheel$filterEntities(CallbackInfoReturnable> cir) {
- if (BackendUtil.canUseInstancing((ClientLevel) (Object) this)) {
+ if (FlwUtil.canUseInstancing((ClientLevel) (Object) this)) {
Iterable entities = cir.getReturnValue();
ArrayList filtered = Lists.newArrayList(entities);
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java
index 0da661d5e..f0642e61c 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java
@@ -10,7 +10,6 @@ import org.spongepowered.asm.mixin.injection.At.Shift;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import com.jozufozu.flywheel.api.backend.BackendManager;
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
import com.jozufozu.flywheel.api.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.api.event.RenderContext;
@@ -56,8 +55,6 @@ public class LevelRendererMixin {
@Inject(at = @At("TAIL"), method = "allChanged")
private void flywheel$refresh(CallbackInfo ci) {
- BackendManager.refresh();
-
MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(level));
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java
index 48c90075b..324114960 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java
@@ -7,9 +7,9 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper;
+import com.jozufozu.flywheel.util.FlwUtil;
import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher;
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -18,7 +18,7 @@ import net.minecraft.world.level.block.entity.BlockEntity;
public class ChunkRebuildHooksMixin {
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
private void flywheel$addAndFilterBEs(ChunkRenderDispatcher.CompiledChunk compiledChunk, Set set, E be, CallbackInfo ci) {
- if (BackendUtil.canUseInstancing(be.getLevel())) {
+ if (FlwUtil.canUseInstancing(be.getLevel())) {
if (InstancingControllerHelper.canInstance(be))
InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be);
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java
index dcbcd7203..601bb9b72 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java
@@ -7,8 +7,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
+import com.jozufozu.flywheel.util.FlwUtil;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.entity.BlockEntity;
@@ -23,7 +23,7 @@ public class InstanceAddMixin {
@Inject(method = "setBlockEntity",
at = @At(value = "INVOKE_ASSIGN", target = "Ljava/util/Map;put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"))
private void flywheel$onBlockEntityAdded(BlockEntity blockEntity, CallbackInfo ci) {
- if (level.isClientSide && BackendUtil.canUseInstancing(level)) {
+ if (level.isClientSide && FlwUtil.canUseInstancing(level)) {
InstancedRenderDispatcher.getBlockEntities(level)
.add(blockEntity);
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java
index 4b4bce61b..4a6df32db 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java
@@ -7,8 +7,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
+import com.jozufozu.flywheel.util.FlwUtil;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.world.level.Level;
@@ -22,7 +22,7 @@ public class InstanceRemoveMixin {
@Inject(at = @At("TAIL"), method = "setRemoved")
private void flywheel$removeInstance(CallbackInfo ci) {
- if (level instanceof ClientLevel && BackendUtil.canUseInstancing(level)) {
+ if (level instanceof ClientLevel && FlwUtil.canUseInstancing(level)) {
InstancedRenderDispatcher.getBlockEntities(level)
.remove((BlockEntity) (Object) this);
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceUpdateMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceUpdateMixin.java
index 17b11ceab..363e1dc0e 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceUpdateMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceUpdateMixin.java
@@ -6,8 +6,8 @@ import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-import com.jozufozu.flywheel.backend.BackendUtil;
import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher;
+import com.jozufozu.flywheel.util.FlwUtil;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.LevelRenderer;
@@ -25,7 +25,7 @@ public class InstanceUpdateMixin {
*/
@Inject(at = @At("TAIL"), method = "setBlockDirty(Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/world/level/block/state/BlockState;)V")
private void flywheel$checkUpdate(BlockPos pos, BlockState lastState, BlockState newState, CallbackInfo ci) {
- if (!BackendUtil.canUseInstancing(level)) {
+ if (!FlwUtil.canUseInstancing(level)) {
return;
}
BlockEntity blockEntity = level.getBlockEntity(pos);
diff --git a/src/main/java/com/jozufozu/flywheel/util/CodecUtil.java b/src/main/java/com/jozufozu/flywheel/util/CodecUtil.java
deleted file mode 100644
index 8263ce501..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/CodecUtil.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.jozufozu.flywheel.util;
-
-import java.util.Collections;
-import java.util.List;
-
-import com.mojang.datafixers.util.Either;
-import com.mojang.serialization.Codec;
-
-public class CodecUtil {
-
- /**
- * Creates a list codec that can be parsed from either a single element or a complete list.
- */
- public static Codec> oneOrMore(Codec codec) {
- return Codec.either(codec.listOf(), codec)
- .xmap(either -> either.map(l -> l, Collections::singletonList), list -> {
- if (list.size() == 1) {
- return Either.right(list.get(0));
- } else {
- return Either.left(list);
- }
- });
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java
index a1d8ec095..ecef7d85e 100644
--- a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java
+++ b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java
@@ -1,18 +1,51 @@
package com.jozufozu.flywheel.util;
import java.util.Collections;
-import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
-import java.util.stream.Stream;
-import org.joml.Math;
-import org.joml.Matrix4f;
-import org.lwjgl.system.MemoryUtil;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.Nullable;
+import com.jozufozu.flywheel.api.FlywheelLevel;
+import com.jozufozu.flywheel.api.backend.BackendManager;
import com.mojang.blaze3d.vertex.PoseStack;
-public class FlwUtil {
+import net.minecraft.client.Minecraft;
+import net.minecraft.world.level.LevelAccessor;
+
+public final class FlwUtil {
+ public static boolean isGameActive() {
+ return !(Minecraft.getInstance().level == null || Minecraft.getInstance().player == null);
+ }
+
+ @Contract("null -> false")
+ public static boolean canUseInstancing(@Nullable LevelAccessor level) {
+ return BackendManager.isOn() && isFlywheelLevel(level);
+ }
+
+ /**
+ * Used to avoid calling Flywheel functions on (fake) levels that don't specifically support it.
+ */
+ public static boolean isFlywheelLevel(@Nullable LevelAccessor level) {
+ if (level == null) {
+ return false;
+ }
+
+ if (!level.isClientSide()) {
+ return false;
+ }
+
+ if (level instanceof FlywheelLevel flywheelLevel && flywheelLevel.supportsFlywheel()) {
+ return true;
+ }
+
+ return level == Minecraft.getInstance().level;
+ }
+
+ public static Set createWeakHashSet() {
+ return Collections.newSetFromMap(new WeakHashMap<>());
+ }
public static PoseStack copyPoseStack(PoseStack stack) {
PoseStack copy = new PoseStack();
@@ -20,176 +53,4 @@ public class FlwUtil {
copy.last().normal().load(stack.last().normal());
return copy;
}
-
- public static int numDigits(int number) {
- // cursed but allegedly the fastest algorithm, taken from https://www.baeldung.com/java-number-of-digits-in-int
- if (number < 100000) {
- if (number < 100) {
- if (number < 10) {
- return 1;
- } else {
- return 2;
- }
- } else {
- if (number < 1000) {
- return 3;
- } else {
- if (number < 10000) {
- return 4;
- } else {
- return 5;
- }
- }
- }
- } else {
- if (number < 10000000) {
- if (number < 1000000) {
- return 6;
- } else {
- return 7;
- }
- } else {
- if (number < 100000000) {
- return 8;
- } else {
- if (number < 1000000000) {
- return 9;
- } else {
- return 10;
- }
- }
- }
- }
- }
-
- public static Stream mapValues(Map, R> map) {
- return map.values()
- .stream();
- }
-
- public static void noop(T object) {
- // noop
- }
-
- public static int align16(int numToRound) {
- return (numToRound + 16 - 1) & -16;
- }
-
- public static Set createWeakHashSet() {
- return Collections.newSetFromMap(new WeakHashMap<>());
- }
-
- /**
- * Writes the frustum planes of the given projection matrix to the given buffer.
- * Uses a different format that is friendly towards an optimized instruction-parallel
- * implementation of sphere-frustum intersection.
- * The format is as follows:
- * {@code vec4(nxX, pxX, nyX, pyX)}
- * {@code vec4(nxY, pxY, nyY, pyY)}
- * {@code vec4(nxZ, pxZ, nyZ, pyZ)}
- * {@code vec4(nxW, pxW, nyW, pyW)}
- * {@code vec2(nzX, pzX)}
- * {@code vec2(nzY, pzY)}
- * {@code vec2(nzZ, pzZ)}
- * {@code vec2(nzW, pzW)}
- *
- * Writes 96 bytes to the buffer.
- *
- * @param ptr The buffer to write the planes to.
- * @param m The projection matrix to compute the frustum planes for.
- */
- public static void writePackedFrustumPlanes(long ptr, Matrix4f m) {
- float nxX, nxY, nxZ, nxW;
- float pxX, pxY, pxZ, pxW;
- float nyX, nyY, nyZ, nyW;
- float pyX, pyY, pyZ, pyW;
- float nzX, nzY, nzZ, nzW;
- float pzX, pzY, pzZ, pzW;
-
- float invl;
- nxX = m.m03() + m.m00();
- nxY = m.m13() + m.m10();
- nxZ = m.m23() + m.m20();
- nxW = m.m33() + m.m30();
- invl = Math.invsqrt(nxX * nxX + nxY * nxY + nxZ * nxZ);
- nxX *= invl;
- nxY *= invl;
- nxZ *= invl;
- nxW *= invl;
-
- pxX = m.m03() - m.m00();
- pxY = m.m13() - m.m10();
- pxZ = m.m23() - m.m20();
- pxW = m.m33() - m.m30();
- invl = Math.invsqrt(pxX * pxX + pxY * pxY + pxZ * pxZ);
- pxX *= invl;
- pxY *= invl;
- pxZ *= invl;
- pxW *= invl;
-
- nyX = m.m03() + m.m01();
- nyY = m.m13() + m.m11();
- nyZ = m.m23() + m.m21();
- nyW = m.m33() + m.m31();
- invl = Math.invsqrt(nyX * nyX + nyY * nyY + nyZ * nyZ);
- nyX *= invl;
- nyY *= invl;
- nyZ *= invl;
- nyW *= invl;
-
- pyX = m.m03() - m.m01();
- pyY = m.m13() - m.m11();
- pyZ = m.m23() - m.m21();
- pyW = m.m33() - m.m31();
- invl = Math.invsqrt(pyX * pyX + pyY * pyY + pyZ * pyZ);
- pyX *= invl;
- pyY *= invl;
- pyZ *= invl;
- pyW *= invl;
-
- nzX = m.m03() + m.m02();
- nzY = m.m13() + m.m12();
- nzZ = m.m23() + m.m22();
- nzW = m.m33() + m.m32();
- invl = Math.invsqrt(nzX * nzX + nzY * nzY + nzZ * nzZ);
- nzX *= invl;
- nzY *= invl;
- nzZ *= invl;
- nzW *= invl;
-
- pzX = m.m03() - m.m02();
- pzY = m.m13() - m.m12();
- pzZ = m.m23() - m.m22();
- pzW = m.m33() - m.m32();
- invl = Math.invsqrt(pzX * pzX + pzY * pzY + pzZ * pzZ);
- pzX *= invl;
- pzY *= invl;
- pzZ *= invl;
- pzW *= invl;
-
- MemoryUtil.memPutFloat(ptr, nxX);
- MemoryUtil.memPutFloat(ptr + 4, pxX);
- MemoryUtil.memPutFloat(ptr + 8, nyX);
- MemoryUtil.memPutFloat(ptr + 12, pyX);
- MemoryUtil.memPutFloat(ptr + 16, nxY);
- MemoryUtil.memPutFloat(ptr + 20, pxY);
- MemoryUtil.memPutFloat(ptr + 24, nyY);
- MemoryUtil.memPutFloat(ptr + 28, pyY);
- MemoryUtil.memPutFloat(ptr + 32, nxZ);
- MemoryUtil.memPutFloat(ptr + 36, pxZ);
- MemoryUtil.memPutFloat(ptr + 40, nyZ);
- MemoryUtil.memPutFloat(ptr + 44, pyZ);
- MemoryUtil.memPutFloat(ptr + 48, nxW);
- MemoryUtil.memPutFloat(ptr + 52, pxW);
- MemoryUtil.memPutFloat(ptr + 56, nyW);
- MemoryUtil.memPutFloat(ptr + 60, pyW);
- MemoryUtil.memPutFloat(ptr + 64, nzX);
- MemoryUtil.memPutFloat(ptr + 68, pzX);
- MemoryUtil.memPutFloat(ptr + 72, nzY);
- MemoryUtil.memPutFloat(ptr + 76, pzY);
- MemoryUtil.memPutFloat(ptr + 80, nzZ);
- MemoryUtil.memPutFloat(ptr + 84, pzZ);
- MemoryUtil.memPutFloat(ptr + 88, nzW);
- MemoryUtil.memPutFloat(ptr + 92, pzW);
- }
}
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java
index 971f24d1c..aa9526224 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java
@@ -7,14 +7,14 @@ import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance;
import com.jozufozu.flywheel.lib.material.Materials;
import com.jozufozu.flywheel.lib.model.SimpleLazyModel;
import com.jozufozu.flywheel.lib.modelpart.ModelPart;
import com.jozufozu.flywheel.lib.struct.OrientedPart;
import com.jozufozu.flywheel.lib.struct.StructTypes;
-import com.jozufozu.flywheel.util.AnimationTickHolder;
+import com.jozufozu.flywheel.lib.util.AnimationTickHolder;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
index 4b95610ca..4e862a238 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java
@@ -7,7 +7,7 @@ import java.util.function.BiFunction;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance;
import com.jozufozu.flywheel.lib.material.Materials;
import com.jozufozu.flywheel.lib.model.SimpleLazyModel;
@@ -15,7 +15,7 @@ import com.jozufozu.flywheel.lib.modelpart.ModelPart;
import com.jozufozu.flywheel.lib.struct.OrientedPart;
import com.jozufozu.flywheel.lib.struct.StructTypes;
import com.jozufozu.flywheel.lib.struct.TransformedPart;
-import com.jozufozu.flywheel.util.AnimationTickHolder;
+import com.jozufozu.flywheel.lib.util.AnimationTickHolder;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
index d4b3bd9da..1e1cc638f 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java
@@ -15,7 +15,7 @@ import com.jozufozu.flywheel.lib.modelpart.ModelPart;
import com.jozufozu.flywheel.lib.struct.StructTypes;
import com.jozufozu.flywheel.lib.struct.TransformedPart;
import com.jozufozu.flywheel.lib.transform.TransformStack;
-import com.jozufozu.flywheel.util.AnimationTickHolder;
+import com.jozufozu.flywheel.lib.util.AnimationTickHolder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Vector3f;
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
index 3cee8063a..da5c1eb84 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java
@@ -6,7 +6,7 @@ import java.util.function.Function;
import com.jozufozu.flywheel.api.event.RenderStage;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.controller.InstanceContext;
-import com.jozufozu.flywheel.api.instancer.InstancePart;
+import com.jozufozu.flywheel.api.struct.InstancePart;
import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance;
import com.jozufozu.flywheel.lib.material.Materials;
import com.jozufozu.flywheel.lib.model.SimpleLazyModel;
@@ -14,7 +14,7 @@ import com.jozufozu.flywheel.lib.modelpart.ModelPart;
import com.jozufozu.flywheel.lib.struct.StructTypes;
import com.jozufozu.flywheel.lib.struct.TransformedPart;
import com.jozufozu.flywheel.lib.transform.TransformStack;
-import com.jozufozu.flywheel.util.AnimationTickHolder;
+import com.jozufozu.flywheel.lib.util.AnimationTickHolder;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Quaternion;
import com.mojang.math.Vector3f;
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/VanillaInstances.java b/src/main/java/com/jozufozu/flywheel/vanilla/VanillaInstances.java
index 5eef3079d..d372d4906 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/VanillaInstances.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/VanillaInstances.java
@@ -27,7 +27,6 @@ import net.minecraft.world.level.block.entity.BlockEntityType;
*
*/
public class VanillaInstances {
-
public static void init() {
configure(BlockEntityType.CHEST)
.alwaysSkipRender()
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java b/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
index fb6a8453e..c149585c4 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
@@ -22,7 +22,7 @@ import com.jozufozu.flywheel.lib.instance.AbstractInstance;
import com.jozufozu.flywheel.lib.model.Models;
import com.jozufozu.flywheel.lib.struct.StructTypes;
import com.jozufozu.flywheel.lib.struct.TransformedPart;
-import com.jozufozu.flywheel.util.AnimationTickHolder;
+import com.jozufozu.flywheel.lib.util.AnimationTickHolder;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;