diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index a7d057b1e..569bc73c6 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -15,18 +15,18 @@ import com.jozufozu.flywheel.handler.ForgeEvents; import com.jozufozu.flywheel.impl.BackendManagerImpl; import com.jozufozu.flywheel.impl.IdRegistryImpl; import com.jozufozu.flywheel.impl.RegistryImpl; -import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.lib.context.Contexts; -import com.jozufozu.flywheel.lib.format.Formats; +import com.jozufozu.flywheel.lib.instance.InstanceTypes; import com.jozufozu.flywheel.lib.material.MaterialIndices; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.Models; import com.jozufozu.flywheel.lib.model.PartialModel; -import com.jozufozu.flywheel.lib.struct.StructTypes; import com.jozufozu.flywheel.lib.util.QuadConverter; import com.jozufozu.flywheel.lib.util.ShadersModHandler; +import com.jozufozu.flywheel.lib.vertex.VertexTypes; import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor; -import com.jozufozu.flywheel.vanilla.VanillaInstances; +import com.jozufozu.flywheel.vanilla.VanillaVisuals; import com.mojang.logging.LogUtils; import net.minecraft.commands.synchronization.ArgumentTypes; @@ -82,9 +82,9 @@ public class Flywheel { forgeEventBus.addListener(Models::onReloadRenderers); forgeEventBus.addListener(DrawBuffer::onReloadRenderers); - forgeEventBus.addListener(InstancedRenderDispatcher::onRenderStage); - forgeEventBus.addListener(InstancedRenderDispatcher::onBeginFrame); - forgeEventBus.addListener(InstancedRenderDispatcher::tick); + forgeEventBus.addListener(VisualizedRenderDispatcher::onRenderStage); + forgeEventBus.addListener(VisualizedRenderDispatcher::onBeginFrame); + forgeEventBus.addListener(VisualizedRenderDispatcher::tick); forgeEventBus.addListener(EntityWorldHandler::onEntityJoinWorld); forgeEventBus.addListener(EntityWorldHandler::onEntityLeaveWorld); @@ -107,14 +107,14 @@ public class Flywheel { ShadersModHandler.init(); - Formats.init(); - StructTypes.init(); + VertexTypes.init(); + InstanceTypes.init(); Materials.init(); Contexts.init(); MaterialIndices.init(); - VanillaInstances.init(); + VanillaVisuals.init(); // https://github.com/Jozufozu/Flywheel/issues/69 // Weird issue with accessor loading. diff --git a/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java b/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java index 09765ca87..d4c266b0f 100644 --- a/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java +++ b/src/main/java/com/jozufozu/flywheel/api/backend/Engine.java @@ -4,7 +4,7 @@ import java.util.List; import com.jozufozu.flywheel.api.event.RenderContext; import com.jozufozu.flywheel.api.event.RenderStage; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; +import com.jozufozu.flywheel.api.instance.InstancerProvider; import com.jozufozu.flywheel.api.task.TaskExecutor; import net.minecraft.client.Camera; diff --git a/src/main/java/com/jozufozu/flywheel/api/event/RenderContext.java b/src/main/java/com/jozufozu/flywheel/api/event/RenderContext.java index 58bed0d54..3f472c68e 100644 --- a/src/main/java/com/jozufozu/flywheel/api/event/RenderContext.java +++ b/src/main/java/com/jozufozu/flywheel/api/event/RenderContext.java @@ -14,7 +14,6 @@ import net.minecraft.client.renderer.RenderBuffers; public record RenderContext(LevelRenderer renderer, ClientLevel level, PoseStack stack, Matrix4f viewProjection, Matrix4f projection, RenderBuffers buffers, Camera camera, FrustumIntersection culler) { - @NotNull public static Matrix4f createViewProjection(PoseStack view, Matrix4f projection) { var viewProjection = projection.copy(); diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/BlockEntityInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/BlockEntityInstance.java deleted file mode 100644 index b5c13a03a..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instance/BlockEntityInstance.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.jozufozu.flywheel.api.instance; - -import java.util.List; - -import com.jozufozu.flywheel.api.struct.InstancePart; - -import net.minecraft.world.level.block.entity.BlockEntity; - -public interface BlockEntityInstance extends Instance { - List getCrumblingParts(); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/EffectInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/EffectInstance.java deleted file mode 100644 index 8289e8938..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instance/EffectInstance.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.jozufozu.flywheel.api.instance; - -import com.jozufozu.flywheel.api.instance.effect.Effect; - -public interface EffectInstance extends Instance { -} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/EntityInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/EntityInstance.java deleted file mode 100644 index 277e25ff2..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instance/EntityInstance.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.jozufozu.flywheel.api.instance; - -import net.minecraft.world.entity.Entity; - -public interface EntityInstance extends Instance { -} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java index eb0f5b241..45252e661 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java @@ -1,48 +1,8 @@ package com.jozufozu.flywheel.api.instance; -/** - * A general interface providing information about any type of thing that could use Flywheel's instanced rendering. - */ public interface Instance { + InstanceType type(); - /** - * Initialize parts here. - */ - void init(); - - /** - * Update instance data here. Good for when data doesn't change very often and when animations are GPU based. - * - *

If your animations are complex or more CPU driven, see {@link DynamicInstance} or {@link TickableInstance}. - */ - void update(); - - /** - * When an instance is reset, the instance is deleted and re-created. - * - *

- * Just before {@link #update()} would be called, {@code shouldReset()} is checked. - * If this function returns {@code true}, then this instance will be {@link #delete deleted}, - * and another instance will be constructed to replace it. This allows for more sane resource - * acquisition compared to trying to update everything within the lifetime of an instance. - *

- * - * @return {@code true} if this instance should be discarded and refreshed. - */ - boolean shouldReset(); - - /** - * Calculate the distance squared between this instance and the given world position. - * - * @param x The x coordinate. - * @param y The y coordinate. - * @param z The z coordinate. - * @return The distance squared between this instance and the given position. - */ - double distanceSquared(double x, double y, double z); - - /** - * Free any acquired resources. - */ - void delete(); + @Deprecated + Instance copy(InstanceHandle handle); } diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/InstanceHandle.java b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceHandle.java new file mode 100644 index 000000000..609d3f4cd --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceHandle.java @@ -0,0 +1,7 @@ +package com.jozufozu.flywheel.api.instance; + +public interface InstanceHandle { + void setChanged(); + + void setDeleted(); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/InstanceType.java b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceType.java new file mode 100644 index 000000000..48df64799 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceType.java @@ -0,0 +1,33 @@ +package com.jozufozu.flywheel.api.instance; + +import com.jozufozu.flywheel.api.layout.BufferLayout; +import com.jozufozu.flywheel.api.registry.Registry; +import com.jozufozu.flywheel.impl.RegistryImpl; + +import net.minecraft.resources.ResourceLocation; + +/** + * An InstanceType contains metadata for a specific instance that Flywheel can interface with. + * + * @param The java representation of the instance. + */ +public interface InstanceType { + static Registry> REGISTRY = RegistryImpl.create(); + + /** + * @param handle A handle that allows you to mark the instance as dirty or deleted. + * @return A new, zeroed instance of I. + */ + I create(InstanceHandle handle); + + /** + * @return The layout of I when buffered. + */ + BufferLayout getLayout(); + + InstanceWriter getWriter(); + + ResourceLocation instanceShader(); + + InstanceVertexTransformer getVertexTransformer(); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/InstanceVertexTransformer.java b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceVertexTransformer.java new file mode 100644 index 000000000..54f5f624f --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceVertexTransformer.java @@ -0,0 +1,9 @@ +package com.jozufozu.flywheel.api.instance; + +import com.jozufozu.flywheel.api.vertex.MutableVertexList; + +import net.minecraft.client.multiplayer.ClientLevel; + +public interface InstanceVertexTransformer { + void transform(MutableVertexList vertexList, I instance, ClientLevel level); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/InstanceWriter.java b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceWriter.java new file mode 100644 index 000000000..821e3e3a5 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/InstanceWriter.java @@ -0,0 +1,11 @@ +package com.jozufozu.flywheel.api.instance; + +/** + * InstanceWriters can quickly consume many instances and write them to some memory address. + */ +public interface InstanceWriter { + /** + * Write the given instance to the given memory address. + */ + void write(final long ptr, final I instance); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instancer/Instancer.java b/src/main/java/com/jozufozu/flywheel/api/instance/Instancer.java similarity index 56% rename from src/main/java/com/jozufozu/flywheel/api/instancer/Instancer.java rename to src/main/java/com/jozufozu/flywheel/api/instance/Instancer.java index 8e9b01dba..17f17fa80 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instancer/Instancer.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/Instancer.java @@ -1,37 +1,35 @@ -package com.jozufozu.flywheel.api.instancer; - -import com.jozufozu.flywheel.api.struct.InstancePart; +package com.jozufozu.flywheel.api.instance; /** * An instancer is how you interact with an instanced model. *

* Instanced models can have many copies, and on most systems it's very fast to draw all of the copies at once. * There is no limit to how many copies an instanced model can have. - * Each copy is represented by an InstanceData object. + * Each copy is represented by an Instance object. *

*

- * When you call {@link #createInstance()} you are given an InstanceData object that you can manipulate however - * you want. The changes you make to the InstanceData object are automatically made visible, and persistent. - * Changing the position of your InstanceData object every frame means that that copy of the model will be in a - * different position in the world each frame. Setting the position of your InstanceData once and not touching it + * When you call {@link #createInstance()} you are given an Instance object that you can manipulate however + * you want. The changes you make to the Instance object are automatically made visible, and persistent. + * Changing the position of your Instance object every frame means that that copy of the model will be in a + * different position in the world each frame. Setting the position of your Instance once and not touching it * again means that your model will be in the same position in the world every frame. This persistence is useful * because it means the properties of your model don't have to be re-evaluated every frame. *

* - * @param

the data that represents a copy of the instanced model. + * @param the data that represents a copy of the instanced model. */ -public interface Instancer

{ +public interface Instancer { /** * @return a handle to a new copy of this model. */ - P createInstance(); + I createInstance(); /** * Populate arr with new instances of this model. * * @param arr An array to fill. */ - default void createInstances(P[] arr) { + default void createInstances(I[] arr) { for (int i = 0; i < arr.length; i++) { arr[i] = createInstance(); } diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/InstancerProvider.java b/src/main/java/com/jozufozu/flywheel/api/instance/InstancerProvider.java new file mode 100644 index 000000000..27d4e26fa --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/InstancerProvider.java @@ -0,0 +1,13 @@ +package com.jozufozu.flywheel.api.instance; + +import com.jozufozu.flywheel.api.event.RenderStage; +import com.jozufozu.flywheel.api.model.Model; + +public interface InstancerProvider { + /** + * Get an instancer for the given instance type, model, and render stage. Calling this method twice with the same arguments will return the same instancer. + * + * @return An instancer for the given instance type, model, and render stage. + */ + Instancer instancer(InstanceType type, Model model, RenderStage stage); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/controller/BlockEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/api/instance/controller/BlockEntityInstancingController.java deleted file mode 100644 index 2eae34f2e..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instance/controller/BlockEntityInstancingController.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.jozufozu.flywheel.api.instance.controller; - -import com.jozufozu.flywheel.api.instance.BlockEntityInstance; - -import net.minecraft.world.level.block.entity.BlockEntity; - -/** - * An instancing controller that will be keyed to a block entity type. - * @param The block entity type. - */ -public interface BlockEntityInstancingController { - /** - * Given a block entity and context, constructs an instance for the block entity. - * - * @param ctx Context for creating an Instance. - * @param blockEntity The block entity to construct an instance for. - * @return The instance. - */ - BlockEntityInstance createInstance(InstanceContext ctx, T blockEntity); - - /** - * Checks if the given block entity should not be rendered normally. - * @param blockEntity The block entity to check. - * @return {@code true} if the block entity should not be rendered normally, {@code false} if it should. - */ - boolean shouldSkipRender(T blockEntity); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/controller/EntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/api/instance/controller/EntityInstancingController.java deleted file mode 100644 index c04cb485d..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instance/controller/EntityInstancingController.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.jozufozu.flywheel.api.instance.controller; - -import com.jozufozu.flywheel.api.instance.EntityInstance; - -import net.minecraft.world.entity.Entity; - -/** - * An instancing controller that will be keyed to an entity type. - * @param The entity type. - */ -public interface EntityInstancingController { - /** - * Given an entity and context, constructs an instance for the entity. - * - * @param ctx Context for creating an Instance. - * @param entity The entity to construct an instance for. - * @return The instance. - */ - EntityInstance createInstance(InstanceContext ctx, T entity); - - /** - * Checks if the given entity should not render normally. - * @param entity The entity to check. - * @return {@code true} if the entity should not render normally, {@code false} if it should. - */ - boolean shouldSkipRender(T entity); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstanceContext.java b/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstanceContext.java deleted file mode 100644 index c60772c9a..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstanceContext.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.jozufozu.flywheel.api.instance.controller; - -import com.jozufozu.flywheel.api.instancer.InstancerProvider; - -import net.minecraft.core.Vec3i; - -/** - * A context object passed on Instance creation. - * - * @param instancerProvider The {@link InstancerProvider} that the instance can use to get instancers to render models. - * @param renderOrigin The origin of the renderer as a world position. - * All models render as if this position is (0, 0, 0). - */ -public record InstanceContext(InstancerProvider instancerProvider, Vec3i renderOrigin) { -} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstancingControllerRegistry.java b/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstancingControllerRegistry.java deleted file mode 100644 index 30b8d0614..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstancingControllerRegistry.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.jozufozu.flywheel.api.instance.controller; - -import org.jetbrains.annotations.Nullable; - -import com.jozufozu.flywheel.impl.InstancingControllerRegistryImpl; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; - -/** - * A utility class for registering and retrieving {@code InstancingController}s. - */ -public final class InstancingControllerRegistry { - /** - * Gets the instancing controller for the given block entity type, if one exists. - * @param type The block entity type to get the instancing controller for. - * @param The type of the block entity. - * @return The instancing controller for the given block entity type, or {@code null} if none exists. - */ - @Nullable - public static BlockEntityInstancingController getController(BlockEntityType type) { - return InstancingControllerRegistryImpl.getController(type); - } - - /** - * Gets the instancing controller for the given entity type, if one exists. - * @param type The entity type to get the instancing controller for. - * @param The type of the entity. - * @return The instancing controller for the given entity type, or {@code null} if none exists. - */ - @Nullable - public static EntityInstancingController getController(EntityType type) { - return InstancingControllerRegistryImpl.getController(type); - } - - /** - * Sets the instancing controller for the given block entity type. - * @param type The block entity type to set the instancing controller for. - * @param instancingController The instancing controller to set. - * @param The type of the block entity. - */ - public static void setController(BlockEntityType type, BlockEntityInstancingController instancingController) { - InstancingControllerRegistryImpl.setController(type, instancingController); - } - - /** - * Sets the instancing controller for the given entity type. - * @param type The entity type to set the instancing controller for. - * @param instancingController The instancing controller to set. - * @param The type of the entity. - */ - public static void setController(EntityType type, EntityInstancingController instancingController) { - InstancingControllerRegistryImpl.setController(type, instancingController); - } - - private InstancingControllerRegistry() { - } -} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java b/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java deleted file mode 100644 index 546bcac05..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.jozufozu.flywheel.api.instance.effect; - -import java.util.Collection; - -import com.jozufozu.flywheel.api.instance.EffectInstance; -import com.jozufozu.flywheel.api.instance.controller.InstanceContext; - -// TODO: add level getter? -// TODO: return single instance instead of many? -public interface Effect { - Collection> createInstances(InstanceContext ctx); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java b/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java deleted file mode 100644 index 13c52909d..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.jozufozu.flywheel.api.instancer; - -import com.jozufozu.flywheel.api.event.RenderStage; -import com.jozufozu.flywheel.api.model.Model; -import com.jozufozu.flywheel.api.struct.InstancePart; -import com.jozufozu.flywheel.api.struct.StructType; - -public interface InstancerProvider { - /** - * Get an instancer for the given struct type, model, and render stage. Calling this method twice with the same arguments will return the same instancer. - * - * @return An instancer for the given struct type, model, and render stage. - */ -

Instancer

instancer(StructType

type, Model model, RenderStage stage); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/layout/BufferLayout.java b/src/main/java/com/jozufozu/flywheel/api/layout/BufferLayout.java index 3a6b37aef..a873f3719 100644 --- a/src/main/java/com/jozufozu/flywheel/api/layout/BufferLayout.java +++ b/src/main/java/com/jozufozu/flywheel/api/layout/BufferLayout.java @@ -7,13 +7,13 @@ import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.gl.array.VertexAttribute; /** - * Classic Vertex Format struct with a clever name. + * Classic Vertex Format with a clever name. * *

* Used for vertices and instances. Describes the layout of a datatype in a buffer object. *

* - * @see com.jozufozu.flywheel.api.struct.StructType + * @see com.jozufozu.flywheel.api.instance.InstanceType * @see VertexType */ public class BufferLayout { diff --git a/src/main/java/com/jozufozu/flywheel/api/pipeline/Pipeline.java b/src/main/java/com/jozufozu/flywheel/api/pipeline/Pipeline.java index bb30e85ec..4e2d746ce 100644 --- a/src/main/java/com/jozufozu/flywheel/api/pipeline/Pipeline.java +++ b/src/main/java/com/jozufozu/flywheel/api/pipeline/Pipeline.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.api.pipeline; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.gl.GLSLVersion; import com.jozufozu.flywheel.glsl.ShaderSources; @@ -9,7 +9,6 @@ import com.jozufozu.flywheel.glsl.SourceComponent; import net.minecraft.resources.ResourceLocation; public interface Pipeline { - GLSLVersion glslVersion(); ResourceLocation vertexShader(); @@ -17,12 +16,12 @@ public interface Pipeline { ResourceLocation fragmentShader(); /** - * Generate the source component necessary to convert a packed {@link StructType} into its shader representation. + * Generate the source component necessary to convert a packed {@link InstanceType} into its shader representation. * - * @return A source component defining functions that unpack a representation of the given struct type. + * @return A source component defining functions that unpack a representation of the given instance type. */ SourceComponent assemble(InstanceAssemblerContext context); - record InstanceAssemblerContext(ShaderSources sources, VertexType vertexType, StructType structType) { + record InstanceAssemblerContext(ShaderSources sources, VertexType vertexType, InstanceType instanceType) { } } diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/Handle.java b/src/main/java/com/jozufozu/flywheel/api/struct/Handle.java deleted file mode 100644 index e688163ad..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/struct/Handle.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.jozufozu.flywheel.api.struct; - -public interface Handle { - void setChanged(); - - void setDeleted(); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/InstancePart.java b/src/main/java/com/jozufozu/flywheel/api/struct/InstancePart.java deleted file mode 100644 index a59824584..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/struct/InstancePart.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.jozufozu.flywheel.api.struct; - -public interface InstancePart { - StructType type(); - - @Deprecated - InstancePart copy(Handle handle); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java b/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java deleted file mode 100644 index 1d734e5fc..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/struct/StructType.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.jozufozu.flywheel.api.struct; - -import com.jozufozu.flywheel.api.layout.BufferLayout; -import com.jozufozu.flywheel.api.registry.Registry; -import com.jozufozu.flywheel.impl.RegistryImpl; - -import net.minecraft.resources.ResourceLocation; - -/** - * A StructType contains metadata for a specific instance struct that Flywheel can interface with. - * - * @param

The java representation of the instance struct. - */ -public interface StructType

{ - static Registry> REGISTRY = RegistryImpl.create(); - - /** - * @param handle A handle that allows you to mark the instance as dirty or deleted. - * @return A new, zeroed instance of S. - */ - P create(Handle handle); - - /** - * @return The layout of S when buffered. - */ - BufferLayout getLayout(); - - StructWriter

getWriter(); - - ResourceLocation instanceShader(); - - StructVertexTransformer

getVertexTransformer(); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/StructVertexTransformer.java b/src/main/java/com/jozufozu/flywheel/api/struct/StructVertexTransformer.java deleted file mode 100644 index b76e87bfa..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/struct/StructVertexTransformer.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.jozufozu.flywheel.api.struct; - -import com.jozufozu.flywheel.api.vertex.MutableVertexList; - -import net.minecraft.client.multiplayer.ClientLevel; - -public interface StructVertexTransformer

{ - void transform(MutableVertexList vertexList, P struct, ClientLevel level); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/struct/StructWriter.java b/src/main/java/com/jozufozu/flywheel/api/struct/StructWriter.java deleted file mode 100644 index 5c8aed15d..000000000 --- a/src/main/java/com/jozufozu/flywheel/api/struct/StructWriter.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.jozufozu.flywheel.api.struct; - -/** - * StructWriters can quickly consume many instances and write them to some memory address. - */ -public interface StructWriter

{ - /** - * Write the given struct to the given memory address. - */ - void write(final long ptr, final P struct); -} diff --git a/src/main/java/com/jozufozu/flywheel/api/visual/BlockEntityVisual.java b/src/main/java/com/jozufozu/flywheel/api/visual/BlockEntityVisual.java new file mode 100644 index 000000000..461de922c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visual/BlockEntityVisual.java @@ -0,0 +1,11 @@ +package com.jozufozu.flywheel.api.visual; + +import java.util.List; + +import com.jozufozu.flywheel.api.instance.Instance; + +import net.minecraft.world.level.block.entity.BlockEntity; + +public interface BlockEntityVisual extends Visual { + List getCrumblingInstances(); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java b/src/main/java/com/jozufozu/flywheel/api/visual/DynamicVisual.java similarity index 57% rename from src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java rename to src/main/java/com/jozufozu/flywheel/api/visual/DynamicVisual.java index ea8c22f79..d515024ff 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/DynamicInstance.java +++ b/src/main/java/com/jozufozu/flywheel/api/visual/DynamicVisual.java @@ -1,48 +1,48 @@ -package com.jozufozu.flywheel.api.instance; +package com.jozufozu.flywheel.api.visual; import org.joml.FrustumIntersection; -import com.jozufozu.flywheel.api.instancer.Instancer; -import com.jozufozu.flywheel.api.struct.InstancePart; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.Instancer; /** - * An interface giving {@link Instance}s a hook to have a function called at - * the start of a frame. By implementing {@link DynamicInstance}, an {@link Instance} + * An interface giving {@link Visual}s a hook to have a function called at + * the start of a frame. By implementing {@link DynamicVisual}, an {@link Visual} * can animate its models in ways that could not be easily achieved by shader attribute * parameterization. * *

If your goal is offloading work to shaders, but you're unsure exactly how you need * to parameterize the instances, you're encouraged to implement this for prototyping. */ -public interface DynamicInstance extends Instance { +public interface DynamicVisual extends Visual { /** * Called every frame, and after initialization. *
- * DISPATCHED IN PARALLEL, don't attempt to mutate anything outside this instance. + * DISPATCHED IN PARALLEL, don't attempt to mutate anything outside this visual. *
- * {@link Instancer}/{@link InstancePart} creation/acquisition is safe here. + * {@link Instancer}/{@link Instance} creation/acquisition is safe here. */ void beginFrame(); /** - * As a further optimization, dynamic instances that are far away are ticked less often. + * As a further optimization, dynamic visuals that are far away are updated less often. * This behavior can be disabled by returning false. * *
You might want to opt out of this if you want your animations to remain smooth * even when far away from the camera. It is recommended to keep this as is, however. * - * @return {@code true} if your instance should be slow ticked. + * @return {@code true} if your visual should be slow updated. */ default boolean decreaseFramerateWithDistance() { return true; } /** - * Check this instance against a frustum.

+ * Check this visual against a frustum.

* An implementor may choose to return a constant to skip the frustum check. * * @param frustum A frustum intersection tester for the current frame. - * @return {@code true} if this instance should be considered for updates. + * @return {@code true} if this visual should be considered for updates. */ boolean isVisible(FrustumIntersection frustum); } diff --git a/src/main/java/com/jozufozu/flywheel/api/visual/Effect.java b/src/main/java/com/jozufozu/flywheel/api/visual/Effect.java new file mode 100644 index 000000000..60a758b1e --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visual/Effect.java @@ -0,0 +1,11 @@ +package com.jozufozu.flywheel.api.visual; + +import java.util.Collection; + +import com.jozufozu.flywheel.api.visualization.VisualizationContext; + +// TODO: add level getter? +// TODO: return single visual instead of many? +public interface Effect { + Collection> createVisuals(VisualizationContext ctx); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/visual/EffectVisual.java b/src/main/java/com/jozufozu/flywheel/api/visual/EffectVisual.java new file mode 100644 index 000000000..5d238007e --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visual/EffectVisual.java @@ -0,0 +1,4 @@ +package com.jozufozu.flywheel.api.visual; + +public interface EffectVisual extends Visual { +} diff --git a/src/main/java/com/jozufozu/flywheel/api/visual/EntityVisual.java b/src/main/java/com/jozufozu/flywheel/api/visual/EntityVisual.java new file mode 100644 index 000000000..886f4fa57 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visual/EntityVisual.java @@ -0,0 +1,6 @@ +package com.jozufozu.flywheel.api.visual; + +import net.minecraft.world.entity.Entity; + +public interface EntityVisual extends Visual { +} diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java b/src/main/java/com/jozufozu/flywheel/api/visual/TickableVisual.java similarity index 50% rename from src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java rename to src/main/java/com/jozufozu/flywheel/api/visual/TickableVisual.java index d7b0afb8d..aa691a537 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java +++ b/src/main/java/com/jozufozu/flywheel/api/visual/TickableVisual.java @@ -1,17 +1,17 @@ -package com.jozufozu.flywheel.api.instance; +package com.jozufozu.flywheel.api.visual; -import com.jozufozu.flywheel.api.instancer.Instancer; -import com.jozufozu.flywheel.api.struct.InstancePart; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.Instancer; /** - * An interface giving {@link Instance}s a hook to have a function called at - * the end of every tick. By implementing {@link TickableInstance}, an {@link Instance} + * An interface giving {@link Visual}s a hook to have a function called at + * the end of every tick. By implementing {@link TickableVisual}, an {@link Visual} * can update frequently, but not every frame. - *
There are a few cases in which this should be considered over {@link DynamicInstance}: + *
There are a few cases in which this should be considered over {@link DynamicVisual}: *

    *
  • - * You'd like to change something about the instance every now and then. - * eg. adding or removing parts, snapping to a different rotation, etc. + * You'd like to change something about the visual every now and then. + * eg. adding or removing instances, snapping to a different rotation, etc. *
  • *
  • * Your BlockEntity does animate, but the animation doesn't have @@ -19,24 +19,23 @@ import com.jozufozu.flywheel.api.struct.InstancePart; *
  • *
*/ -public interface TickableInstance extends Instance { - +public interface TickableVisual extends Visual { /** * Called every tick, and after initialization.

- * DISPATCHED IN PARALLEL, don't attempt to mutate anything outside of this instance + * DISPATCHED IN PARALLEL, don't attempt to mutate anything outside of this visual * without proper synchronization.

- * {@link Instancer}/{@link InstancePart} creation/acquisition is safe here. + * {@link Instancer}/{@link Instance} creation/acquisition is safe here. */ void tick(); /** - * As a further optimization, tickable instances that are far away are ticked less often. + * As a further optimization, tickable visuals that are far away are ticked less often. * This behavior can be disabled by returning false. * *
You might want to opt out of this if you want your animations to remain smooth * even when far away from the camera. It is recommended to keep this as is, however. * - * @return {@code true} if your instance should be slow ticked. + * @return {@code true} if your visual should be slow ticked. */ default boolean decreaseTickRateWithDistance() { return true; diff --git a/src/main/java/com/jozufozu/flywheel/api/visual/Visual.java b/src/main/java/com/jozufozu/flywheel/api/visual/Visual.java new file mode 100644 index 000000000..77aeccb76 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visual/Visual.java @@ -0,0 +1,47 @@ +package com.jozufozu.flywheel.api.visual; + +/** + * A general interface providing information about any type of thing that could use Flywheel's visualized rendering. + */ +public interface Visual { + /** + * Initialize instances here. + */ + void init(); + + /** + * Update instances here. Good for when instances don't change very often and when animations are GPU based. + * + *

If your animations are complex or more CPU driven, see {@link DynamicVisual} or {@link TickableVisual}. + */ + void update(); + + /** + * When a visual is reset, the visual is deleted and re-created. + * + *

+ * Just before {@link #update()} would be called, {@code shouldReset()} is checked. + * If this function returns {@code true}, then this visual will be {@link #delete deleted}, + * and another visual will be constructed to replace it. This allows for more sane resource + * acquisition compared to trying to update everything within the lifetime of a visual. + *

+ * + * @return {@code true} if this visual should be discarded and refreshed. + */ + boolean shouldReset(); + + /** + * Calculate the distance squared between this visual and the given world position. + * + * @param x The x coordinate. + * @param y The y coordinate. + * @param z The z coordinate. + * @return The distance squared between this visual and the given position. + */ + double distanceSquared(double x, double y, double z); + + /** + * Free any acquired resources. + */ + void delete(); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/visualization/BlockEntityVisualizer.java b/src/main/java/com/jozufozu/flywheel/api/visualization/BlockEntityVisualizer.java new file mode 100644 index 000000000..295f6b351 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visualization/BlockEntityVisualizer.java @@ -0,0 +1,27 @@ +package com.jozufozu.flywheel.api.visualization; + +import com.jozufozu.flywheel.api.visual.BlockEntityVisual; + +import net.minecraft.world.level.block.entity.BlockEntity; + +/** + * A visualizer that will be keyed to a block entity type. + * @param The block entity type. + */ +public interface BlockEntityVisualizer { + /** + * Given a block entity and context, constructs a visual for the block entity. + * + * @param ctx Context for creating a visual. + * @param blockEntity The block entity to construct a visual for. + * @return The visual. + */ + BlockEntityVisual createVisual(VisualizationContext ctx, T blockEntity); + + /** + * Checks if the given block entity should not be rendered normally. + * @param blockEntity The block entity to check. + * @return {@code true} if the block entity should not be rendered normally, {@code false} if it should. + */ + boolean shouldSkipRender(T blockEntity); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/visualization/EntityVisualizer.java b/src/main/java/com/jozufozu/flywheel/api/visualization/EntityVisualizer.java new file mode 100644 index 000000000..a4b26d6e7 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visualization/EntityVisualizer.java @@ -0,0 +1,27 @@ +package com.jozufozu.flywheel.api.visualization; + +import com.jozufozu.flywheel.api.visual.EntityVisual; + +import net.minecraft.world.entity.Entity; + +/** + * A visualizer that will be keyed to an entity type. + * @param The entity type. + */ +public interface EntityVisualizer { + /** + * Given an entity and context, constructs a visual for the entity. + * + * @param ctx Context for creating a visual. + * @param entity The entity to construct a visual for. + * @return The visual. + */ + EntityVisual createVisual(VisualizationContext ctx, T entity); + + /** + * Checks if the given entity should not render normally. + * @param entity The entity to check. + * @return {@code true} if the entity should not render normally, {@code false} if it should. + */ + boolean shouldSkipRender(T entity); +} diff --git a/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizationContext.java b/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizationContext.java new file mode 100644 index 000000000..cc2c30d53 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizationContext.java @@ -0,0 +1,15 @@ +package com.jozufozu.flywheel.api.visualization; + +import com.jozufozu.flywheel.api.instance.InstancerProvider; + +import net.minecraft.core.Vec3i; + +/** + * A context object passed on visual creation. + * + * @param instancerProvider The {@link InstancerProvider} that the visual can use to get instancers to render models. + * @param renderOrigin The origin of the renderer as a world position. + * All models render as if this position is (0, 0, 0). + */ +public record VisualizationContext(InstancerProvider instancerProvider, Vec3i renderOrigin) { +} diff --git a/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizerRegistry.java b/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizerRegistry.java new file mode 100644 index 000000000..13625526f --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/visualization/VisualizerRegistry.java @@ -0,0 +1,60 @@ +package com.jozufozu.flywheel.api.visualization; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.impl.VisualizerRegistryImpl; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +/** + * A utility class for registering and retrieving {@code Visualizer}s. + */ +public final class VisualizerRegistry { + /** + * Gets the visualizer for the given block entity type, if one exists. + * @param type The block entity type to get the visualizer for. + * @param The type of the block entity. + * @return The visualizer for the given block entity type, or {@code null} if none exists. + */ + @Nullable + public static BlockEntityVisualizer getVisualizer(BlockEntityType type) { + return VisualizerRegistryImpl.getVisualizer(type); + } + + /** + * Gets the visualizer for the given entity type, if one exists. + * @param type The entity type to get the visualizer for. + * @param The type of the entity. + * @return The visualizer for the given entity type, or {@code null} if none exists. + */ + @Nullable + public static EntityVisualizer getVisualizer(EntityType type) { + return VisualizerRegistryImpl.getVisualizer(type); + } + + /** + * Sets the visualizer for the given block entity type. + * @param type The block entity type to set the visualizer for. + * @param visualizer The visualizer to set. + * @param The type of the block entity. + */ + public static void setVisualizer(BlockEntityType type, BlockEntityVisualizer visualizer) { + VisualizerRegistryImpl.setVisualizer(type, visualizer); + } + + /** + * Sets the visualizer for the given entity type. + * @param type The entity type to set the visualizer for. + * @param visualizer The visualizer to set. + * @param The type of the entity. + */ + public static void setVisualizer(EntityType type, EntityVisualizer visualizer) { + VisualizerRegistryImpl.setVisualizer(type, visualizer); + } + + private VisualizerRegistry() { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContext.java b/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContext.java index e481d1c78..75ea4ab99 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContext.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContext.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.backend.compile; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.InstanceType; -public record CullingContext(StructType structType) { +public record CullingContext(InstanceType instanceType) { } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContextSet.java b/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContextSet.java index e23755e51..6f7d98279 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContextSet.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/CullingContextSet.java @@ -4,13 +4,13 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.InstanceType; public class CullingContextSet { static CullingContextSet create() { var builder = new CullingContextSet(); - for (StructType structType : StructType.REGISTRY) { - builder.add(structType); + for (InstanceType instanceType : InstanceType.REGISTRY) { + builder.add(instanceType); } return builder; } @@ -29,8 +29,8 @@ public class CullingContextSet { return contexts.size(); } - private void add(StructType structType) { - var ctx = new CullingContext(structType); + private void add(InstanceType instanceType) { + var ctx = new CullingContext(instanceType); contexts.add(ctx); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java index 2101a59c8..61d8150e5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java @@ -13,8 +13,8 @@ import java.util.stream.Collectors; import com.google.common.collect.ImmutableList; import com.jozufozu.flywheel.Flywheel; import com.jozufozu.flywheel.api.context.Context; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.pipeline.Pipeline; -import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.uniform.ShaderUniforms; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.Pipelines; @@ -45,7 +45,7 @@ public class FlwCompiler { final ShaderCompiler shaderCompiler; final Map pipelinePrograms = new HashMap<>(); - final Map, GlProgram> cullingPrograms = new HashMap<>(); + final Map, GlProgram> cullingPrograms = new HashMap<>(); final List errors = new ArrayList<>(); public FlwCompiler(ShaderSources sources) { @@ -101,7 +101,7 @@ public class FlwCompiler { private void finish() { long compileEnd = System.nanoTime(); - int programCount = pipelineContexts.size() + StructType.REGISTRY.getAll().size(); + int programCount = pipelineContexts.size() + InstanceType.REGISTRY.getAll().size(); int shaderCount = shaderCompiler.shaderCount(); int errorCount = errors.size(); var elapsed = StringUtil.formatTime(compileEnd - compileStart); @@ -124,12 +124,12 @@ public class FlwCompiler { shaderCompiler.delete(); } - public GlProgram getPipelineProgram(VertexType vertexType, StructType structType, Context contextShader, Pipeline pipelineShader) { - return pipelinePrograms.get(new PipelineContext(vertexType, structType, contextShader, pipelineShader)); + public GlProgram getPipelineProgram(VertexType vertexType, InstanceType instanceType, Context contextShader, Pipeline pipelineShader) { + return pipelinePrograms.get(new PipelineContext(vertexType, instanceType, contextShader, pipelineShader)); } - public GlProgram getCullingProgram(StructType structType) { - return cullingPrograms.get(structType); + public GlProgram getCullingProgram(InstanceType instanceType) { + return cullingPrograms.get(instanceType); } private void compilePipelineContext(PipelineContext ctx) { @@ -150,14 +150,14 @@ public class FlwCompiler { } private void compileComputeCuller(CullingContext ctx) { - var computeComponents = getComputeComponents(ctx.structType()); + var computeComponents = getComputeComponents(ctx.instanceType()); var result = shaderCompiler.compile(GLSLVersion.V460, ShaderType.COMPUTE, computeComponents); if (result == null) { return; } - cullingPrograms.put(ctx.structType(), link(result.handle())); + cullingPrograms.put(ctx.instanceType(), link(result.handle())); } private GlProgram link(int... shaders) { @@ -172,11 +172,11 @@ public class FlwCompiler { private ImmutableList getVertexComponents(PipelineContext ctx) { var instanceAssembly = ctx.pipelineShader() - .assemble(new Pipeline.InstanceAssemblerContext(sources, ctx.vertexType(), ctx.structType())); + .assemble(new Pipeline.InstanceAssemblerContext(sources, ctx.vertexType(), ctx.instanceType())); var layout = sources.find(ctx.vertexType() .layoutShader()); - var instance = sources.find(ctx.structType() + var instance = sources.find(ctx.instanceType() .instanceShader()); var context = sources.find(ctx.contextShader() .vertexShader()); @@ -194,9 +194,9 @@ public class FlwCompiler { return ImmutableList.of(uniformComponent, fragmentMaterialComponent, context, pipeline); } - private ImmutableList getComputeComponents(StructType structType) { - var instanceAssembly = new IndirectComponent(sources, structType); - var instance = sources.find(structType.instanceShader()); + private ImmutableList getComputeComponents(InstanceType instanceType) { + var instanceAssembly = new IndirectComponent(sources, instanceType); + var instance = sources.find(instanceType.instanceShader()); var pipeline = sources.find(Pipelines.Files.INDIRECT_CULL); return ImmutableList.of(uniformComponent, instanceAssembly, instance, pipeline); diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContext.java b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContext.java index 21165069b..0fe8edc68 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContext.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContext.java @@ -1,17 +1,17 @@ package com.jozufozu.flywheel.backend.compile; import com.jozufozu.flywheel.api.context.Context; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.pipeline.Pipeline; -import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.vertex.VertexType; /** * Represents the entire context of a program's usage. * * @param vertexType The vertexType the program should be adapted for. - * @param structType The instance shader to use. + * @param instanceType The instance shader to use. * @param contextShader The context shader to use. */ -public record PipelineContext(VertexType vertexType, StructType structType, Context contextShader, +public record PipelineContext(VertexType vertexType, InstanceType instanceType, Context contextShader, Pipeline pipelineShader) { } diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContextSet.java b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContextSet.java index 56fa3db8d..2f4079168 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContextSet.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/PipelineContextSet.java @@ -9,8 +9,8 @@ import java.util.stream.Collectors; import com.jozufozu.flywheel.api.backend.Backend; import com.jozufozu.flywheel.api.context.Context; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.pipeline.Pipeline; -import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.lib.context.Contexts; @@ -24,9 +24,9 @@ public class PipelineContextSet { static PipelineContextSet create() { var builder = new PipelineContextSet(); for (Pipeline pipelineShader : availablePipelineShaders()) { - for (StructType structType : StructType.REGISTRY) { + for (InstanceType instanceType : InstanceType.REGISTRY) { for (VertexType vertexType : VertexType.REGISTRY) { - builder.add(vertexType, structType, Contexts.WORLD, pipelineShader); + builder.add(vertexType, instanceType, Contexts.WORLD, pipelineShader); } } } @@ -50,8 +50,8 @@ public class PipelineContextSet { return contexts.size(); } - private void add(VertexType vertexType, StructType structType, Context world, Pipeline pipelineShader) { - var ctx = new PipelineContext(vertexType, structType, world, pipelineShader); + private void add(VertexType vertexType, InstanceType instanceType, Context world, Pipeline pipelineShader) { + var ctx = new PipelineContext(vertexType, instanceType, world, pipelineShader); contexts.add(ctx); } 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 8b43f4d82..4d4679c2b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractInstancer.java @@ -3,45 +3,42 @@ package com.jozufozu.flywheel.backend.engine; import java.util.ArrayList; import java.util.BitSet; -import com.jozufozu.flywheel.api.instancer.Instancer; -import com.jozufozu.flywheel.api.struct.InstancePart; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.Instancer; -public abstract class AbstractInstancer

implements Instancer

{ - public final StructType

type; +public abstract class AbstractInstancer implements Instancer { + public final InstanceType type; - // Lock for all instance data, only needs to be used in methods that may run on the TaskExecutor. + // Lock for all instances, only needs to be used in methods that may run on the TaskExecutor. protected final Object lock = new Object(); - protected final ArrayList

data = new ArrayList<>(); - protected final ArrayList handles = new ArrayList<>(); + protected final ArrayList instances = new ArrayList<>(); + protected final ArrayList handles = new ArrayList<>(); // TODO: atomic bitset? protected final BitSet changed = new BitSet(); protected final BitSet deleted = new BitSet(); - protected AbstractInstancer(StructType

type) { + protected AbstractInstancer(InstanceType type) { this.type = type; } - /** - * @return a handle to a new copy of this model. - */ @Override - public P createInstance() { + public I createInstance() { synchronized (lock) { - var i = data.size(); - var handle = new HandleImpl(this, i); - P instanceData = type.create(handle); + var i = instances.size(); + var handle = new InstanceHandleImpl(this, i); + I instance = type.create(handle); - data.add(instanceData); + instances.add(instance); handles.add(handle); changed.set(i); - return instanceData; + return instance; } } public int getInstanceCount() { - return data.size(); + return instances.size(); } public void notifyDirty(int index) { @@ -68,7 +65,7 @@ public abstract class AbstractInstancer

implements Insta } // Figure out which elements are to be removed. - final int oldSize = this.data.size(); + final int oldSize = this.instances.size(); int removeCount = deleted.cardinality(); final int newSize = oldSize - removeCount; @@ -79,10 +76,10 @@ public abstract class AbstractInstancer

implements Insta if (i != j) { var handle = handles.get(i); - P element = data.get(i); + I instance = instances.get(i); handles.set(j, handle); - data.set(j, element); + instances.set(j, instance); handle.setIndex(j); changed.set(j); @@ -90,18 +87,18 @@ public abstract class AbstractInstancer

implements Insta } deleted.clear(); - data.subList(newSize, oldSize) + instances.subList(newSize, oldSize) .clear(); handles.subList(newSize, oldSize) .clear(); } /** - * Clear all instance data without freeing resources. + * Clear all instances without freeing resources. */ public void clear() { - handles.forEach(HandleImpl::clear); - data.clear(); + handles.forEach(InstanceHandleImpl::clear); + instances.clear(); handles.clear(); changed.clear(); deleted.clear(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/HandleImpl.java b/src/main/java/com/jozufozu/flywheel/backend/engine/InstanceHandleImpl.java similarity index 68% rename from src/main/java/com/jozufozu/flywheel/backend/engine/HandleImpl.java rename to src/main/java/com/jozufozu/flywheel/backend/engine/InstanceHandleImpl.java index 28ebebcda..2cc8f059e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/HandleImpl.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/InstanceHandleImpl.java @@ -1,12 +1,12 @@ package com.jozufozu.flywheel.backend.engine; -import com.jozufozu.flywheel.api.struct.Handle; +import com.jozufozu.flywheel.api.instance.InstanceHandle; -public class HandleImpl implements Handle { +public class InstanceHandleImpl implements InstanceHandle { private final AbstractInstancer instancer; private int index; - public HandleImpl(AbstractInstancer instancer, int index) { + public InstanceHandleImpl(AbstractInstancer instancer, int index) { this.instancer = instancer; this.index = 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 3cbf4458a..d868ffb54 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/InstancerKey.java @@ -1,9 +1,9 @@ package com.jozufozu.flywheel.backend.engine; import com.jozufozu.flywheel.api.event.RenderStage; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; 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) { +public record InstancerKey(InstanceType type, Model model, RenderStage stage) { } 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 fc5a58870..568b4bb74 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,10 +5,10 @@ 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.Instancer; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.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; import com.mojang.blaze3d.vertex.PoseStack; @@ -24,7 +24,7 @@ public class BatchingEngine implements Engine { private final BatchingDrawTracker drawTracker = new BatchingDrawTracker(); @Override - public

Instancer

instancer(StructType

type, Model model, RenderStage stage) { + public Instancer instancer(InstanceType type, Model model, RenderStage stage) { return transformManager.getInstancer(type, model, stage); } 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 214a6c2c4..fc839f2d8 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,11 +15,11 @@ 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.Instancer; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.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; @@ -42,9 +42,9 @@ public class BatchingTransformManager { } @SuppressWarnings("unchecked") - public

Instancer

getInstancer(StructType

type, Model model, RenderStage stage) { - InstancerKey

key = new InstancerKey<>(type, model, stage); - CPUInstancer

instancer = (CPUInstancer

) instancers.get(key); + public Instancer getInstancer(InstanceType type, Model model, RenderStage stage) { + InstancerKey key = new InstancerKey<>(type, model, stage); + CPUInstancer instancer = (CPUInstancer) instancers.get(key); if (instancer == null) { instancer = new CPUInstancer<>(type); instancers.put(key, instancer); 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 6ac7aad78..b6df62f00 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 @@ -2,21 +2,21 @@ package com.jozufozu.flywheel.backend.engine.batching; import java.util.List; -import com.jozufozu.flywheel.api.struct.InstancePart; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.backend.engine.AbstractInstancer; -public class CPUInstancer

extends AbstractInstancer

{ - public CPUInstancer(StructType

type) { +public class CPUInstancer extends AbstractInstancer { + public CPUInstancer(InstanceType type) { super(type); } - public List

getRange(int start, int end) { - return data.subList(start, end); + public List getRange(int start, int end) { + return instances.subList(start, end); } - public List

getAll() { - return data; + public List getAll() { + return instances; } public void update() { 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 61f1c61ba..ac3fa16b9 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,9 +2,9 @@ package com.jozufozu.flywheel.backend.engine.batching; import java.util.List; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceVertexTransformer; import com.jozufozu.flywheel.api.material.Material; -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; @@ -15,15 +15,15 @@ import com.mojang.math.Matrix4f; import net.minecraft.client.multiplayer.ClientLevel; -public class TransformCall

{ - private final CPUInstancer

instancer; +public class TransformCall { + private final CPUInstancer instancer; private final Material material; private final BatchedMeshPool.BufferedMesh mesh; private final int meshVertexCount; private final int meshByteSize; - public TransformCall(CPUInstancer

instancer, Material material, BatchedMeshPool.BufferedMesh mesh) { + public TransformCall(CPUInstancer instancer, Material material, BatchedMeshPool.BufferedMesh mesh) { this.instancer = instancer; this.material = material; this.mesh = mesh; @@ -64,18 +64,18 @@ public class TransformCall

{ transformList(vertexList, instancer.getAll(), matrices, level); } - public void transformList(ReusableVertexList vertexList, List

parts, PoseStack.Pose matrices, ClientLevel level) { + public void transformList(ReusableVertexList vertexList, List instances, PoseStack.Pose matrices, ClientLevel level) { long anchorPtr = vertexList.ptr(); int totalVertexCount = vertexList.vertexCount(); vertexList.vertexCount(meshVertexCount); - StructVertexTransformer

structVertexTransformer = instancer.type.getVertexTransformer(); + InstanceVertexTransformer instanceVertexTransformer = instancer.type.getVertexTransformer(); - for (P p : parts) { + for (I instance : instances) { mesh.copyTo(vertexList.ptr()); - structVertexTransformer.transform(vertexList, p, level); + instanceVertexTransformer.transform(vertexList, instance, level); vertexList.ptr(vertexList.ptr() + meshByteSize); } 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 ecdabd46e..bc4129fc3 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 @@ -5,9 +5,9 @@ import java.util.List; import com.google.common.collect.ImmutableList; import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.api.instance.InstanceType; 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; @@ -30,11 +30,11 @@ public class IndirectComponent implements SourceComponent { private final ImmutableList included; public IndirectComponent(Pipeline.InstanceAssemblerContext ctx) { - this(ctx.sources(), ctx.structType()); + this(ctx.sources(), ctx.instanceType()); } - public IndirectComponent(ShaderSources sources, StructType structType) { - this.layoutItems = structType.getLayout().layoutItems; + public IndirectComponent(ShaderSources sources, InstanceType instanceType) { + this.layoutItems = instanceType.getLayout().layoutItems; included = ImmutableList.of(sources.find(Pipelines.Files.UTIL_TYPES)); } 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 9636b512b..7de4719e8 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,8 +12,8 @@ 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.struct.InstancePart; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.Pipelines; import com.jozufozu.flywheel.backend.compile.FlwCompiler; @@ -22,14 +22,14 @@ import com.jozufozu.flywheel.gl.shader.GlProgram; import com.jozufozu.flywheel.lib.context.Contexts; import com.jozufozu.flywheel.lib.util.QuadConverter; -public class IndirectCullingGroup

{ +public class IndirectCullingGroup { private static final int BARRIER_BITS = GL_SHADER_STORAGE_BARRIER_BIT | GL_COMMAND_BARRIER_BIT; final GlProgram compute; final GlProgram draw; private final VertexType vertexType; - private final long objectStride; + private final long instanceStride; final IndirectBuffers buffers; @@ -38,18 +38,18 @@ public class IndirectCullingGroup

{ int vertexArray; - final IndirectDrawSet

drawSet = new IndirectDrawSet<>(); + final IndirectDrawSet drawSet = new IndirectDrawSet<>(); private boolean hasCulledThisFrame; private boolean needsMemoryBarrier; private int instanceCountThisFrame; - IndirectCullingGroup(StructType

structType, VertexType vertexType) { + IndirectCullingGroup(InstanceType instanceType, VertexType vertexType) { this.vertexType = vertexType; - objectStride = structType.getLayout() + instanceStride = instanceType.getLayout() .getStride(); - buffers = new IndirectBuffers(objectStride); + buffers = new IndirectBuffers(instanceStride); buffers.createBuffers(); buffers.createObjectStorage(128); buffers.createDrawStorage(2); @@ -62,8 +62,8 @@ public class IndirectCullingGroup

{ .quads2Tris(2048).glBuffer; setupVertexArray(); - compute = FlwCompiler.INSTANCE.getCullingProgram(structType); - draw = FlwCompiler.INSTANCE.getPipelineProgram(vertexType, structType, Contexts.WORLD, Pipelines.INDIRECT); + compute = FlwCompiler.INSTANCE.getCullingProgram(instanceType); + draw = FlwCompiler.INSTANCE.getPipelineProgram(vertexType, instanceType, Contexts.WORLD, Pipelines.INDIRECT); } private void setupVertexArray() { @@ -110,7 +110,7 @@ public class IndirectCullingGroup

{ buffers.updateCounts(instanceCountThisFrame, drawSet.size()); meshPool.flush(); - uploadInstanceData(); + uploadInstances(); uploadIndirectCommands(); UniformBuffer.syncAndBind(compute); @@ -143,7 +143,7 @@ public class IndirectCullingGroup

{ } } - private void uploadInstanceData() { + private void uploadInstances() { long objectPtr = buffers.objectPtr; long batchIDPtr = buffers.batchPtr; @@ -153,7 +153,7 @@ public class IndirectCullingGroup

{ .getInstanceCount(); batch.writeObjects(objectPtr, batchIDPtr, i); - objectPtr += instanceCount * objectStride; + objectPtr += instanceCount * instanceStride; batchIDPtr += instanceCount * IndirectBuffers.INT_SIZE; } 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 d9a18a032..798c28411 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,12 +3,12 @@ package com.jozufozu.flywheel.backend.engine.indirect; import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.event.RenderStage; +import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.api.struct.InstancePart; import com.jozufozu.flywheel.lib.material.MaterialIndices; -public class IndirectDraw

{ - private final IndirectInstancer

instancer; +public class IndirectDraw { + private final IndirectInstancer instancer; private final IndirectMeshPool.BufferedMesh mesh; private final Material material; private final RenderStage stage; @@ -19,7 +19,7 @@ public class IndirectDraw

{ private int baseInstance = -1; private boolean needsFullWrite = true; - public IndirectDraw(IndirectInstancer

instancer, Material material, IndirectMeshPool.BufferedMesh mesh, RenderStage stage) { + public IndirectDraw(IndirectInstancer instancer, Material material, IndirectMeshPool.BufferedMesh mesh, RenderStage stage) { this.instancer = instancer; this.material = material; this.mesh = mesh; @@ -29,7 +29,7 @@ public class IndirectDraw

{ this.fragmentMaterialID = MaterialIndices.getFragmentShaderIndex(material); } - public IndirectInstancer

instancer() { + public IndirectInstancer instancer() { return instancer; } 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 49ab8402c..5dff01a79 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,10 +6,10 @@ import java.util.List; import java.util.Map; import com.jozufozu.flywheel.api.event.RenderStage; -import com.jozufozu.flywheel.api.instancer.Instancer; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.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; @@ -18,12 +18,12 @@ public class IndirectDrawManager { private final Map, IndirectInstancer> instancers = new HashMap<>(); private final List uninitializedInstancers = new ArrayList<>(); private final List> initializedInstancers = new ArrayList<>(); - public final Map, VertexType>, IndirectCullingGroup> renderLists = new HashMap<>(); + public final Map, VertexType>, IndirectCullingGroup> renderLists = new HashMap<>(); @SuppressWarnings("unchecked") - public

Instancer

getInstancer(StructType

type, Model model, RenderStage stage) { - InstancerKey

key = new InstancerKey<>(type, model, stage); - IndirectInstancer

instancer = (IndirectInstancer

) instancers.get(key); + public Instancer getInstancer(InstanceType type, Model model, RenderStage stage) { + InstancerKey key = new InstancerKey<>(type, model, stage); + IndirectInstancer instancer = (IndirectInstancer) instancers.get(key); if (instancer == null) { instancer = new IndirectInstancer<>(type); instancers.put(key, instancer); @@ -58,13 +58,13 @@ public class IndirectDrawManager { } @SuppressWarnings("unchecked") - private

void add(IndirectInstancer

instancer, Model model, RenderStage stage) { + private void add(IndirectInstancer instancer, Model model, RenderStage stage) { var meshes = model.getMeshes(); for (var entry : meshes.entrySet()) { var material = entry.getKey(); var mesh = entry.getValue(); - var indirectList = (IndirectCullingGroup

) renderLists.computeIfAbsent(Pair.of(instancer.type, mesh.getVertexType()), p -> new IndirectCullingGroup<>(p.first(), p.second())); + var indirectList = (IndirectCullingGroup) renderLists.computeIfAbsent(Pair.of(instancer.type, mesh.getVertexType()), p -> new IndirectCullingGroup<>(p.first(), p.second())); indirectList.drawSet.add(instancer, material, stage, indirectList.meshPool.alloc(mesh)); 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 7f0080794..c9b77c7c7 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,13 +11,13 @@ import java.util.List; import java.util.Map; import com.jozufozu.flywheel.api.event.RenderStage; +import com.jozufozu.flywheel.api.instance.Instance; import com.jozufozu.flywheel.api.material.Material; -import com.jozufozu.flywheel.api.struct.InstancePart; import com.jozufozu.flywheel.lib.material.MaterialIndices; -public class IndirectDrawSet

{ +public class IndirectDrawSet { - final List> indirectDraws = new ArrayList<>(); + final List> indirectDraws = new ArrayList<>(); final Map> multiDraws = new EnumMap<>(RenderStage.class); @@ -29,7 +29,7 @@ public class IndirectDrawSet

{ return indirectDraws.size(); } - public void add(IndirectInstancer

instancer, Material material, RenderStage stage, IndirectMeshPool.BufferedMesh bufferedMesh) { + public void add(IndirectInstancer instancer, Material material, RenderStage stage, IndirectMeshPool.BufferedMesh bufferedMesh) { indirectDraws.add(new IndirectDraw<>(instancer, material, bufferedMesh, stage)); determineMultiDraws(); } @@ -48,7 +48,7 @@ public class IndirectDrawSet

{ // TODO: Better material equality. Really we only need to bin by the results of the setup method. multiDraws.clear(); // sort by stage, then material - indirectDraws.sort(Comparator.comparing(IndirectDraw

::stage) + indirectDraws.sort(Comparator.comparing(IndirectDraw::stage) .thenComparing(draw -> MaterialIndices.getMaterialIndex(draw.material()))); for (int start = 0, i = 0; i < indirectDraws.size(); i++) { 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 5c53a2261..4d63901f0 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,10 +7,10 @@ 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.Instancer; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.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; import com.jozufozu.flywheel.gl.GlTextureUnit; @@ -34,7 +34,7 @@ public class IndirectEngine implements Engine { } @Override - public

Instancer

instancer(StructType

type, Model model, RenderStage stage) { + public Instancer instancer(InstanceType type, Model model, RenderStage stage) { return drawManager.getInstancer(type, model, stage); } 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 e5f6282fa..b5ebe9624 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,15 +2,15 @@ package com.jozufozu.flywheel.backend.engine.indirect; import org.lwjgl.system.MemoryUtil; -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.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.InstanceWriter; import com.jozufozu.flywheel.backend.engine.AbstractInstancer; -public class IndirectInstancer

extends AbstractInstancer

{ +public class IndirectInstancer extends AbstractInstancer { private final long instanceStride; - public IndirectInstancer(StructType

type) { + public IndirectInstancer(InstanceType type) { super(type); this.instanceStride = type.getLayout() .getStride(); @@ -21,11 +21,11 @@ public class IndirectInstancer

extends AbstractInstancer } public void writeSparse(long objectPtr, long batchIDPtr, int batchID) { - int count = data.size(); - StructWriter

writer = type.getWriter(); + int count = instances.size(); + InstanceWriter 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)); + writer.write(objectPtr + instanceStride * i, instances.get(i)); // write batchID MemoryUtil.memPutInt(batchIDPtr + IndirectBuffers.INT_SIZE * i, batchID); @@ -34,8 +34,8 @@ public class IndirectInstancer

extends AbstractInstancer } public void writeFull(long objectPtr, long batchIDPtr, int batchID) { - StructWriter

writer = type.getWriter(); - for (var object : data) { + InstanceWriter writer = type.getWriter(); + for (I object : instances) { // write object writer.write(objectPtr, object); objectPtr += instanceStride; 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 dbd5040c1..8769eec4c 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,10 +4,10 @@ import java.util.HashSet; import java.util.Set; import com.jozufozu.flywheel.Flywheel; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.InstanceWriter; 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; import com.jozufozu.flywheel.gl.array.GlVertexArray; import com.jozufozu.flywheel.gl.buffer.GlBuffer; @@ -15,14 +15,14 @@ import com.jozufozu.flywheel.gl.buffer.GlBufferType; import com.jozufozu.flywheel.gl.buffer.GlBufferUsage; import com.jozufozu.flywheel.gl.buffer.MappedBuffer; -public class GPUInstancer

extends AbstractInstancer

{ +public class GPUInstancer extends AbstractInstancer { private final BufferLayout instanceFormat; private final int instanceStride; private final Set boundTo = new HashSet<>(); private GlBuffer vbo; - public GPUInstancer(StructType

type) { + public GPUInstancer(InstanceType type) { super(type); instanceFormat = type.getLayout(); instanceStride = instanceFormat.getStride(); @@ -52,7 +52,7 @@ public class GPUInstancer

extends AbstractInstancer

{ } private void ensureBufferCapacity() { - int count = data.size(); + int count = instances.size(); int byteSize = instanceStride * count; if (vbo.ensureCapacity(byteSize)) { // The vbo has moved, so we need to re-bind attributes @@ -65,7 +65,7 @@ public class GPUInstancer

extends AbstractInstancer

{ return; } - int count = data.size(); + int count = instances.size(); long clearStart = instanceStride * (long) count; long clearLength = vbo.getSize() - clearStart; @@ -73,10 +73,10 @@ public class GPUInstancer

extends AbstractInstancer

{ buf.clear(clearStart, clearLength); long ptr = buf.getPtr(); - StructWriter

writer = type.getWriter(); + InstanceWriter writer = type.getWriter(); for (int i = changed.nextSetBit(0); i >= 0 && i < count; i = changed.nextSetBit(i + 1)) { - writer.write(ptr + instanceStride * i, data.get(i)); + writer.write(ptr + instanceStride * i, instances.get(i)); } changed.clear(); diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedArraysComponent.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedArraysComponent.java index fa716004c..363b52b1e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedArraysComponent.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancedArraysComponent.java @@ -23,7 +23,7 @@ public class InstancedArraysComponent implements SourceComponent { private final int baseIndex; public InstancedArraysComponent(Pipeline.InstanceAssemblerContext ctx) { - this.layoutItems = ctx.structType() + this.layoutItems = ctx.instanceType() .getLayout().layoutItems; this.baseIndex = ctx.vertexType() .getLayout() 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 d6165ddb8..5890fe7a7 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,11 +14,11 @@ 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.Instancer; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.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; @@ -34,9 +34,9 @@ public class InstancingDrawManager { } @SuppressWarnings("unchecked") - public

Instancer

getInstancer(StructType

type, Model model, RenderStage stage) { - InstancerKey

key = new InstancerKey<>(type, model, stage); - GPUInstancer

instancer = (GPUInstancer

) instancers.get(key); + public Instancer getInstancer(InstanceType type, Model model, RenderStage stage) { + InstancerKey key = new InstancerKey<>(type, model, stage); + GPUInstancer instancer = (GPUInstancer) instancers.get(key); if (instancer == null) { instancer = new GPUInstancer<>(type); instancers.put(key, instancer); 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 80e0a6b3a..683340a32 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,10 +8,10 @@ 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.Instancer; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.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; @@ -41,7 +41,7 @@ public class InstancingEngine implements Engine { } @Override - public

Instancer

instancer(StructType

type, Model model, RenderStage stage) { + public Instancer instancer(InstanceType type, Model model, RenderStage stage) { return drawManager.getInstancer(type, model, stage); } @@ -104,9 +104,9 @@ public class InstancingEngine implements Engine { private void setup(ShaderState desc) { var material = desc.material(); var vertexType = desc.vertexType(); - var structType = desc.instanceType(); + var instanceType = desc.instanceType(); - var program = FlwCompiler.INSTANCE.getPipelineProgram(vertexType, structType, context, Pipelines.INSTANCED_ARRAYS); + var program = FlwCompiler.INSTANCE.getPipelineProgram(vertexType, instanceType, context, Pipelines.INSTANCED_ARRAYS); UniformBuffer.syncAndBind(program); var uniformLocation = program.getUniformLocation("_flw_materialID_instancing"); 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 420cfac1b..9a2645fc6 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 @@ -1,8 +1,8 @@ package com.jozufozu.flywheel.backend.engine.instancing; +import com.jozufozu.flywheel.api.instance.InstanceType; 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 vertexType, StructType instanceType) { +public record ShaderState(Material material, VertexType vertexType, InstanceType instanceType) { } diff --git a/src/main/java/com/jozufozu/flywheel/extension/BlockEntityTypeExtension.java b/src/main/java/com/jozufozu/flywheel/extension/BlockEntityTypeExtension.java index 65f6b63f5..e81515fe0 100644 --- a/src/main/java/com/jozufozu/flywheel/extension/BlockEntityTypeExtension.java +++ b/src/main/java/com/jozufozu/flywheel/extension/BlockEntityTypeExtension.java @@ -2,13 +2,13 @@ package com.jozufozu.flywheel.extension; import org.jetbrains.annotations.Nullable; -import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; +import com.jozufozu.flywheel.api.visualization.BlockEntityVisualizer; import net.minecraft.world.level.block.entity.BlockEntity; public interface BlockEntityTypeExtension { @Nullable - BlockEntityInstancingController flywheel$getInstancingController(); + BlockEntityVisualizer flywheel$getVisualizer(); - void flywheel$setInstancingController(@Nullable BlockEntityInstancingController instancingController); + void flywheel$setVisualizer(@Nullable BlockEntityVisualizer visualizer); } diff --git a/src/main/java/com/jozufozu/flywheel/extension/EntityTypeExtension.java b/src/main/java/com/jozufozu/flywheel/extension/EntityTypeExtension.java index 0bce72734..b3cbe36fc 100644 --- a/src/main/java/com/jozufozu/flywheel/extension/EntityTypeExtension.java +++ b/src/main/java/com/jozufozu/flywheel/extension/EntityTypeExtension.java @@ -2,13 +2,13 @@ package com.jozufozu.flywheel.extension; import org.jetbrains.annotations.Nullable; -import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; +import com.jozufozu.flywheel.api.visualization.EntityVisualizer; import net.minecraft.world.entity.Entity; public interface EntityTypeExtension { @Nullable - EntityInstancingController flywheel$getInstancingController(); + EntityVisualizer flywheel$getVisualizer(); - void flywheel$setInstancingController(@Nullable EntityInstancingController instancingController); + void flywheel$setVisualizer(@Nullable EntityVisualizer visualizer); } diff --git a/src/main/java/com/jozufozu/flywheel/gl/buffer/ElementBuffer.java b/src/main/java/com/jozufozu/flywheel/gl/buffer/ElementBuffer.java index 590fe5ce3..00dd26e97 100644 --- a/src/main/java/com/jozufozu/flywheel/gl/buffer/ElementBuffer.java +++ b/src/main/java/com/jozufozu/flywheel/gl/buffer/ElementBuffer.java @@ -3,7 +3,6 @@ package com.jozufozu.flywheel.gl.buffer; import com.mojang.blaze3d.vertex.VertexFormat; public class ElementBuffer { - protected final int elementCount; protected final VertexFormat.IndexType eboIndexType; public final int glBuffer; 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 084c1f707..7691a8efa 100644 --- a/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java +++ b/src/main/java/com/jozufozu/flywheel/glsl/error/ErrorReporter.java @@ -112,5 +112,4 @@ public class ErrorReporter { LOGGER.error(builder.toString()); } - } diff --git a/src/main/java/com/jozufozu/flywheel/handler/EntityWorldHandler.java b/src/main/java/com/jozufozu/flywheel/handler/EntityWorldHandler.java index 9cefeb4a3..409aa3f00 100644 --- a/src/main/java/com/jozufozu/flywheel/handler/EntityWorldHandler.java +++ b/src/main/java/com/jozufozu/flywheel/handler/EntityWorldHandler.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.handler; -import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.util.FlwUtil; import net.minecraft.world.level.Level; @@ -14,8 +14,8 @@ public class EntityWorldHandler { return; } - if (FlwUtil.canUseInstancing(level)) { - InstancedRenderDispatcher.getEntities(level) + if (FlwUtil.canUseVisualization(level)) { + VisualizedRenderDispatcher.getEntities(level) .queueAdd(event.getEntity()); } } @@ -26,8 +26,8 @@ public class EntityWorldHandler { return; } - if (FlwUtil.canUseInstancing(level)) { - InstancedRenderDispatcher.getEntities(level) + if (FlwUtil.canUseVisualization(level)) { + VisualizedRenderDispatcher.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 af04a70ed..e15e67ecd 100644 --- a/src/main/java/com/jozufozu/flywheel/handler/ForgeEvents.java +++ b/src/main/java/com/jozufozu/flywheel/handler/ForgeEvents.java @@ -3,7 +3,7 @@ package com.jozufozu.flywheel.handler; import java.util.ArrayList; import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.lib.light.LightUpdater; import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker; import com.jozufozu.flywheel.util.FlwUtil; @@ -22,7 +22,7 @@ public class ForgeEvents { debug.add(""); debug.add("Flywheel: " + Flywheel.getVersion()); - InstancedRenderDispatcher.addDebugInfo(debug); + VisualizedRenderDispatcher.addDebugInfo(debug); debug.add("Memory Usage: CPU: " + StringUtil.formatBytes(FlwMemoryTracker.getCPUMemory()) + ", GPU: " + StringUtil.formatBytes(FlwMemoryTracker.getGPUMemory())); } diff --git a/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java b/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java index c2e4c73d8..9ec6761ec 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java +++ b/src/main/java/com/jozufozu/flywheel/impl/BackendManagerImpl.java @@ -8,7 +8,7 @@ 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.impl.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.lib.backend.SimpleBackend; import com.mojang.logging.LogUtils; @@ -63,7 +63,7 @@ public final class BackendManagerImpl { backend = chooseBackend(); if (level != null) { - InstancedRenderDispatcher.resetInstanceWorld(level); + VisualizedRenderDispatcher.resetVisualWorld(level); } } diff --git a/src/main/java/com/jozufozu/flywheel/impl/InstancingControllerRegistryImpl.java b/src/main/java/com/jozufozu/flywheel/impl/InstancingControllerRegistryImpl.java deleted file mode 100644 index 522bdfde9..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/InstancingControllerRegistryImpl.java +++ /dev/null @@ -1,38 +0,0 @@ -package com.jozufozu.flywheel.impl; - -import org.jetbrains.annotations.Nullable; - -import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; -import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; -import com.jozufozu.flywheel.extension.BlockEntityTypeExtension; -import com.jozufozu.flywheel.extension.EntityTypeExtension; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; - -//TODO: Add freezing -@SuppressWarnings("unchecked") -public final class InstancingControllerRegistryImpl { - @Nullable - public static BlockEntityInstancingController getController(BlockEntityType type) { - return ((BlockEntityTypeExtension) type).flywheel$getInstancingController(); - } - - @Nullable - public static EntityInstancingController getController(EntityType type) { - return ((EntityTypeExtension) type).flywheel$getInstancingController(); - } - - public static void setController(BlockEntityType type, BlockEntityInstancingController instancingController) { - ((BlockEntityTypeExtension) type).flywheel$setInstancingController(instancingController); - } - - public static void setController(EntityType type, EntityInstancingController instancingController) { - ((EntityTypeExtension) type).flywheel$setInstancingController(instancingController); - } - - private InstancingControllerRegistryImpl() { - } -} diff --git a/src/main/java/com/jozufozu/flywheel/impl/VisualizerRegistryImpl.java b/src/main/java/com/jozufozu/flywheel/impl/VisualizerRegistryImpl.java new file mode 100644 index 000000000..00b4876d0 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/VisualizerRegistryImpl.java @@ -0,0 +1,38 @@ +package com.jozufozu.flywheel.impl; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.api.visualization.BlockEntityVisualizer; +import com.jozufozu.flywheel.api.visualization.EntityVisualizer; +import com.jozufozu.flywheel.extension.BlockEntityTypeExtension; +import com.jozufozu.flywheel.extension.EntityTypeExtension; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +//TODO: Add freezing +@SuppressWarnings("unchecked") +public final class VisualizerRegistryImpl { + @Nullable + public static BlockEntityVisualizer getVisualizer(BlockEntityType type) { + return ((BlockEntityTypeExtension) type).flywheel$getVisualizer(); + } + + @Nullable + public static EntityVisualizer getVisualizer(EntityType type) { + return ((EntityTypeExtension) type).flywheel$getVisualizer(); + } + + public static void setVisualizer(BlockEntityType type, BlockEntityVisualizer visualizer) { + ((BlockEntityTypeExtension) type).flywheel$setVisualizer(visualizer); + } + + public static void setVisualizer(EntityType type, EntityVisualizer visualizer) { + ((EntityTypeExtension) type).flywheel$setVisualizer(visualizer); + } + + private VisualizerRegistryImpl() { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancingControllerHelper.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancingControllerHelper.java deleted file mode 100644 index b95b90763..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancingControllerHelper.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing; - -import org.jetbrains.annotations.Nullable; - -import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; -import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; -import com.jozufozu.flywheel.api.instance.controller.InstancingControllerRegistry; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; - -public final class InstancingControllerHelper { - @SuppressWarnings("unchecked") - @Nullable - public static BlockEntityInstancingController getController(T blockEntity) { - return InstancingControllerRegistry.getController((BlockEntityType) blockEntity.getType()); - } - - @SuppressWarnings("unchecked") - @Nullable - public static EntityInstancingController getController(T entity) { - return InstancingControllerRegistry.getController((EntityType) entity.getType()); - } - - /** - * Checks if the given block entity can be instanced. - * @param type The block entity to check. - * @param The block entity. - * @return {@code true} if the block entity can be instanced. - */ - public static boolean canInstance(T blockEntity) { - return getController(blockEntity) != null; - } - - /** - * Checks if the given entity can be instanced. - * @param type The entity to check. - * @param The entity. - * @return {@code true} if the entity can be instanced. - */ - public static boolean canInstance(T entity) { - return getController(entity) != null; - } - - /** - * Checks if the given block entity is instanced and should not be rendered normally. - * @param blockEntity The block entity to check. - * @param The type of the block entity. - * @return {@code true} if the block entity is instanced and should not be rendered normally. - */ - public static boolean shouldSkipRender(T blockEntity) { - BlockEntityInstancingController controller = getController(blockEntity); - if (controller == null) { - return false; - } - return controller.shouldSkipRender(blockEntity); - } - - /** - * Checks if the given entity is instanced and should not be rendered normally. - * @param entity The entity to check. - * @param The type of the entity. - * @return {@code true} if the entity is instanced and should not be rendered normally. - */ - public static boolean shouldSkipRender(T entity) { - EntityInstancingController controller = getController(entity); - if (controller == null) { - return false; - } - return controller.shouldSkipRender(entity); - } - - private InstancingControllerHelper() { - } -} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/EffectInstanceManager.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/EffectInstanceManager.java deleted file mode 100644 index c30187f05..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/EffectInstanceManager.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing.manager; - -import java.util.Collection; - -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.api.instance.effect.Effect; -import com.jozufozu.flywheel.impl.instancing.storage.One2ManyStorage; -import com.jozufozu.flywheel.impl.instancing.storage.Storage; - -public class EffectInstanceManager extends InstanceManager { - private final EffectStorage storage; - - public EffectInstanceManager(Engine engine) { - storage = new EffectStorage(engine); - } - - @Override - protected Storage getStorage() { - return storage; - } - - private static class EffectStorage extends One2ManyStorage { - public EffectStorage(Engine engine) { - super(engine); - } - - @Override - protected Collection createRaw(Effect obj) { - return obj.createInstances(new InstanceContext(engine, engine.renderOrigin())); - } - - @Override - public boolean willAccept(Effect obj) { - return true; - } - } -} 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 deleted file mode 100644 index 5e1474f55..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/EntityInstanceManager.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing.manager; - -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.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; - -public class EntityInstanceManager extends InstanceManager { - private final EntityStorage storage; - - public EntityInstanceManager(Engine engine) { - storage = new EntityStorage(engine); - } - - @Override - protected Storage getStorage() { - return storage; - } - - private static class EntityStorage extends One2OneStorage { - public EntityStorage(Engine engine) { - super(engine); - } - - @Override - @Nullable - protected Instance createRaw(Entity obj) { - var controller = InstancingControllerHelper.getController(obj); - if (controller == null) { - return null; - } - - return controller.createInstance(new InstanceContext(engine, engine.renderOrigin()), obj); - } - - @Override - public boolean willAccept(Entity entity) { - if (!entity.isAlive()) { - return false; - } - - if (!InstancingControllerHelper.canInstance(entity)) { - return false; - } - - Level level = entity.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 deleted file mode 100644 index ff0c5535d..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/InstanceManager.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing.manager; - -import java.util.List; -import java.util.Queue; -import java.util.concurrent.ConcurrentLinkedQueue; -import java.util.function.Consumer; - -import org.joml.FrustumIntersection; - -import com.jozufozu.flywheel.api.instance.DynamicInstance; -import com.jozufozu.flywheel.api.instance.Instance; -import com.jozufozu.flywheel.api.instance.TickableInstance; -import com.jozufozu.flywheel.api.task.TaskExecutor; -import com.jozufozu.flywheel.config.FlwConfig; -import com.jozufozu.flywheel.impl.instancing.ratelimit.BandedPrimeLimiter; -import com.jozufozu.flywheel.impl.instancing.ratelimit.DistanceUpdateLimiter; -import com.jozufozu.flywheel.impl.instancing.ratelimit.NonLimiter; -import com.jozufozu.flywheel.impl.instancing.storage.Storage; -import com.jozufozu.flywheel.impl.instancing.storage.Transaction; - -public abstract class InstanceManager { - private final Queue> queue = new ConcurrentLinkedQueue<>(); - - protected DistanceUpdateLimiter tickLimiter; - protected DistanceUpdateLimiter frameLimiter; - - public InstanceManager() { - tickLimiter = createUpdateLimiter(); - frameLimiter = createUpdateLimiter(); - } - - protected abstract Storage getStorage(); - - protected DistanceUpdateLimiter createUpdateLimiter() { - if (FlwConfig.get().limitUpdates()) { - return new BandedPrimeLimiter(); - } else { - return new NonLimiter(); - } - } - - /** - * Get the number of game objects that are currently being instanced. - * - * @return The object count. - */ - public int getInstanceCount() { - return getStorage().getAllInstances().size(); - } - - public void add(T obj) { - if (!getStorage().willAccept(obj)) { - return; - } - - getStorage().add(obj); - } - - public void queueAdd(T obj) { - if (!getStorage().willAccept(obj)) { - return; - } - - 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. - * - *

- * By default this is the only hook an {@link Instance} has to change its internal state. This is the lowest frequency - * update hook {@link Instance} gets. For more frequent updates, see {@link TickableInstance} and - * {@link DynamicInstance}. - *

- * - * @param obj the object to update. - */ - public void update(T obj) { - if (!getStorage().willAccept(obj)) { - return; - } - - getStorage().update(obj); - } - - public void queueUpdate(T obj) { - if (!getStorage().willAccept(obj)) { - return; - } - - queue.add(Transaction.update(obj)); - } - - public void recreateAll() { - getStorage().recreateAll(); - } - - public void invalidate() { - getStorage().invalidate(); - } - - protected void processQueue() { - var storage = getStorage(); - Transaction transaction; - while ((transaction = queue.poll()) != null) { - transaction.apply(storage); - } - } - - /** - * Ticks the InstanceManager. - * - *

- * {@link TickableInstance}s get ticked. - *
- * Queued updates are processed. - *

- */ - public void tick(TaskExecutor executor, double cameraX, double cameraY, double cameraZ) { - tickLimiter.tick(); - processQueue(); - - var instances = getStorage().getTickableInstances(); - distributeWork(executor, instances, instance -> tickInstance(instance, cameraX, cameraY, cameraZ)); - } - - protected void tickInstance(TickableInstance instance, double cameraX, double cameraY, double cameraZ) { - if (!instance.decreaseTickRateWithDistance() || tickLimiter.shouldUpdate(instance.distanceSquared(cameraX, cameraY, cameraZ))) { - instance.tick(); - } - } - - public void beginFrame(TaskExecutor executor, double cameraX, double cameraY, double cameraZ, FrustumIntersection frustum) { - frameLimiter.tick(); - processQueue(); - - var instances = getStorage().getDynamicInstances(); - distributeWork(executor, instances, instance -> updateInstance(instance, cameraX, cameraY, cameraZ, frustum)); - } - - protected void updateInstance(DynamicInstance instance, double cameraX, double cameraY, double cameraZ, FrustumIntersection frustum) { - if (!instance.decreaseFramerateWithDistance() || frameLimiter.shouldUpdate(instance.distanceSquared(cameraX, cameraY, cameraZ))) { - if (instance.isVisible(frustum)) { - instance.beginFrame(); - } - } - } - - private static void distributeWork(TaskExecutor executor, List instances, Consumer action) { - final int size = instances.size(); - final int threadCount = executor.getThreadCount(); - - if (threadCount == 1) { - executor.execute(() -> instances.forEach(action)); - } else { - final int stride = Math.max(size / (threadCount * 2), 1); - for (int start = 0; start < size; start += stride) { - int end = Math.min(start + stride, size); - - var sub = instances.subList(start, end); - executor.execute(() -> sub.forEach(action)); - } - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/AbstractStorage.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/AbstractStorage.java deleted file mode 100644 index ce811413a..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/AbstractStorage.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing.storage; - -import java.util.ArrayList; -import java.util.List; - -import com.jozufozu.flywheel.api.backend.Engine; -import com.jozufozu.flywheel.api.instance.DynamicInstance; -import com.jozufozu.flywheel.api.instance.Instance; -import com.jozufozu.flywheel.api.instance.TickableInstance; - -public abstract class AbstractStorage implements Storage { - protected final Engine engine; - protected final List tickableInstances = new ArrayList<>(); - protected final List dynamicInstances = new ArrayList<>(); - - protected AbstractStorage(Engine engine) { - this.engine = engine; - } - - @Override - public List getTickableInstances() { - return tickableInstances; - } - - @Override - public List getDynamicInstances() { - return dynamicInstances; - } - - protected void setup(Instance instance) { - instance.init(); - - if (instance instanceof TickableInstance tickable) { - tickableInstances.add(tickable); - tickable.tick(); - } - - if (instance instanceof DynamicInstance dynamic) { - dynamicInstances.add(dynamic); - dynamic.beginFrame(); - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Action.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Action.java deleted file mode 100644 index 99f993f90..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Action.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing.storage; - -public enum Action { - ADD, - REMOVE, - UPDATE, -} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/One2ManyStorage.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/One2ManyStorage.java deleted file mode 100644 index e75838054..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/One2ManyStorage.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing.storage; - -import java.util.Collection; -import java.util.List; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.Multimap; -import com.jozufozu.flywheel.api.backend.Engine; -import com.jozufozu.flywheel.api.instance.Instance; - -public abstract class One2ManyStorage extends AbstractStorage { - private final Multimap allInstances = HashMultimap.create(); - - public One2ManyStorage(Engine engine) { - super(engine); - } - - @Override - public Collection getAllInstances() { - return allInstances.values(); - } - - @Override - public void add(T obj) { - Collection instances = allInstances.get(obj); - - if (instances.isEmpty()) { - create(obj); - } - } - - @Override - public void remove(T obj) { - Collection instances = allInstances.removeAll(obj); - - if (instances.isEmpty()) { - return; - } - - tickableInstances.removeAll(instances); - dynamicInstances.removeAll(instances); - instances.forEach(Instance::delete); - } - - @Override - public void update(T obj) { - Collection instances = allInstances.get(obj); - - if (instances.isEmpty()) { - return; - } - - // TODO: shouldReset cannot be checked here because all instances are created at once - instances.forEach(Instance::update); - } - - @Override - public void recreateAll() { - tickableInstances.clear(); - dynamicInstances.clear(); - allInstances.values().forEach(Instance::delete); - - List objects = List.copyOf(allInstances.keySet()); - allInstances.clear(); - objects.forEach(this::create); - } - - @Override - public void invalidate() { - tickableInstances.clear(); - dynamicInstances.clear(); - allInstances.values().forEach(Instance::delete); - allInstances.clear(); - } - - private void create(T obj) { - Collection instances = createRaw(obj); - - if (!instances.isEmpty()) { - instances.forEach(this::setup); - allInstances.putAll(obj, instances); - } - } - - protected abstract Collection createRaw(T obj); -} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/One2OneStorage.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/One2OneStorage.java deleted file mode 100644 index f806ef557..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/One2OneStorage.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing.storage; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -import org.jetbrains.annotations.Nullable; - -import com.jozufozu.flywheel.api.backend.Engine; -import com.jozufozu.flywheel.api.instance.Instance; - -public abstract class One2OneStorage extends AbstractStorage { - private final Map instances = new HashMap<>(); - - public One2OneStorage(Engine engine) { - super(engine); - } - - @Override - public Collection getAllInstances() { - return instances.values(); - } - - @Override - public void add(T obj) { - Instance instance = instances.get(obj); - - if (instance == null) { - create(obj); - } - } - - @Override - public void remove(T obj) { - Instance instance = instances.remove(obj); - - if (instance == null) { - return; - } - - tickableInstances.remove(instance); - dynamicInstances.remove(instance); - instance.delete(); - } - - @Override - public void update(T obj) { - Instance instance = instances.get(obj); - - if (instance == null) { - return; - } - - // resetting instances is by default used to handle block state changes. - if (instance.shouldReset()) { - // delete and re-create the instance. - // resetting an instance supersedes updating it. - remove(obj); - create(obj); - } else { - instance.update(); - } - } - - @Override - public void recreateAll() { - tickableInstances.clear(); - dynamicInstances.clear(); - instances.replaceAll((obj, instance) -> { - instance.delete(); - - Instance out = createRaw(obj); - - if (out != null) { - setup(out); - } - - return out; - }); - } - - @Override - public void invalidate() { - tickableInstances.clear(); - dynamicInstances.clear(); - instances.values().forEach(Instance::delete); - instances.clear(); - } - - private void create(T obj) { - Instance instance = createRaw(obj); - - if (instance != null) { - setup(instance); - instances.put(obj, instance); - } - } - - @Nullable - protected abstract Instance createRaw(T obj); -} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Storage.java b/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Storage.java deleted file mode 100644 index 78c3a474e..000000000 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Storage.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.jozufozu.flywheel.impl.instancing.storage; - -import java.util.Collection; -import java.util.List; - -import com.jozufozu.flywheel.api.instance.DynamicInstance; -import com.jozufozu.flywheel.api.instance.Instance; -import com.jozufozu.flywheel.api.instance.TickableInstance; - -public interface Storage { - Collection getAllInstances(); - - List getTickableInstances(); - - List getDynamicInstances(); - - /** - * Is the given object currently capable of being added? - * - * @return true if the object is currently capable of being instanced. - */ - boolean willAccept(T obj); - - void add(T obj); - - void remove(T obj); - - void update(T obj); - - void recreateAll(); - - void invalidate(); -} 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 3f541d157..a91805349 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/vertex/InferredVertexListImpl.java +++ b/src/main/java/com/jozufozu/flywheel/impl/vertex/InferredVertexListImpl.java @@ -3,8 +3,8 @@ package com.jozufozu.flywheel.impl.vertex; import org.lwjgl.system.MemoryUtil; import com.jozufozu.flywheel.api.vertex.ReusableVertexList; -import com.jozufozu.flywheel.lib.format.AbstractVertexList; import com.jozufozu.flywheel.lib.math.RenderMath; +import com.jozufozu.flywheel.lib.vertex.AbstractVertexList; import com.mojang.blaze3d.vertex.VertexFormat; import net.minecraft.client.renderer.LightTexture; diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualWorld.java similarity index 64% rename from src/main/java/com/jozufozu/flywheel/impl/instancing/InstanceWorld.java rename to src/main/java/com/jozufozu/flywheel/impl/visualization/VisualWorld.java index e974d0b69..b2f0a6837 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstanceWorld.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualWorld.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.impl.instancing; +package com.jozufozu.flywheel.impl.visualization; import java.util.List; @@ -8,17 +8,17 @@ import com.jozufozu.flywheel.api.backend.BackendManager; 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.instance.DynamicInstance; -import com.jozufozu.flywheel.api.instance.TickableInstance; -import com.jozufozu.flywheel.api.instance.effect.Effect; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visual.Effect; +import com.jozufozu.flywheel.api.visual.TickableVisual; 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; -import com.jozufozu.flywheel.impl.instancing.manager.EffectInstanceManager; -import com.jozufozu.flywheel.impl.instancing.manager.EntityInstanceManager; -import com.jozufozu.flywheel.impl.instancing.manager.InstanceManager; +import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityVisualManager; +import com.jozufozu.flywheel.impl.visualization.manager.EffectVisualManager; +import com.jozufozu.flywheel.impl.visualization.manager.EntityVisualManager; +import com.jozufozu.flywheel.impl.visualization.manager.VisualManager; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.LevelAccessor; @@ -28,43 +28,43 @@ import net.minecraft.world.level.block.entity.BlockEntity; * A manager class for a single world where instancing is supported. */ // AutoCloseable is implemented to prevent leaking this object from WorldAttached -public class InstanceWorld implements AutoCloseable { +public class VisualWorld implements AutoCloseable { private final Engine engine; private final ParallelTaskExecutor taskExecutor; - private final InstanceManager blockEntities; - private final InstanceManager entities; - private final InstanceManager effects; + private final VisualManager blockEntities; + private final VisualManager entities; + private final VisualManager effects; - public InstanceWorld(LevelAccessor level) { + public VisualWorld(LevelAccessor level) { engine = BackendManager.getBackend().createEngine(level); taskExecutor = FlwTaskExecutor.get(); - blockEntities = new BlockEntityInstanceManager(engine); - entities = new EntityInstanceManager(engine); - effects = new EffectInstanceManager(engine); + blockEntities = new BlockEntityVisualManager(engine); + entities = new EntityVisualManager(engine); + effects = new EffectVisualManager(engine); } public Engine getEngine() { return engine; } - public InstanceManager getBlockEntities() { + public VisualManager getBlockEntities() { return blockEntities; } - public InstanceManager getEntities() { + public VisualManager getEntities() { return entities; } - public InstanceManager getEffects() { + public VisualManager getEffects() { return effects; } /** - * Tick the instances after the game has ticked: + * Tick the visuals after the game has ticked: *

- * Call {@link TickableInstance#tick()} on all instances in this world. + * Call {@link TickableVisual#tick()} on all visuals in this world. *

*/ public void tick(double cameraX, double cameraY, double cameraZ) { @@ -78,7 +78,7 @@ public class InstanceWorld implements AutoCloseable { *

* Check and update the render origin. *
- * Call {@link DynamicInstance#beginFrame()} on all instances in this world. + * Call {@link DynamicVisual#beginFrame()} on all visuals in this world. *

*/ public void beginFrame(RenderContext context) { @@ -109,7 +109,7 @@ public class InstanceWorld implements AutoCloseable { } /** - * Draw all instances for the given stage. + * Draw all visuals for the given stage. */ public void renderStage(RenderContext context, RenderStage stage) { taskExecutor.syncPoint(); @@ -117,15 +117,15 @@ public class InstanceWorld implements AutoCloseable { } public void addDebugInfo(List info) { - info.add("B: " + blockEntities.getInstanceCount() - + ", E: " + entities.getInstanceCount() - + ", F: " + effects.getInstanceCount()); + info.add("B: " + blockEntities.getVisualCount() + + ", E: " + entities.getVisualCount() + + ", F: " + effects.getVisualCount()); info.add("Update limiting: " + FlwCommands.boolToText(FlwConfig.get().limitUpdates()).getString()); engine.addDebugInfo(info); } /** - * Free all acquired resources and invalidate this instance world. + * Free all acquired resources and invalidate this visual world. */ public void delete() { taskExecutor.discardAndAwait(); diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationHelper.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationHelper.java new file mode 100644 index 000000000..cb0678adf --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizationHelper.java @@ -0,0 +1,77 @@ +package com.jozufozu.flywheel.impl.visualization; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.api.visualization.BlockEntityVisualizer; +import com.jozufozu.flywheel.api.visualization.EntityVisualizer; +import com.jozufozu.flywheel.api.visualization.VisualizerRegistry; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +public final class VisualizationHelper { + @SuppressWarnings("unchecked") + @Nullable + public static BlockEntityVisualizer getVisualizer(T blockEntity) { + return VisualizerRegistry.getVisualizer((BlockEntityType) blockEntity.getType()); + } + + @SuppressWarnings("unchecked") + @Nullable + public static EntityVisualizer getVisualizer(T entity) { + return VisualizerRegistry.getVisualizer((EntityType) entity.getType()); + } + + /** + * Checks if the given block entity can be visualized. + * @param type The block entity to check. + * @param The block entity. + * @return {@code true} if the block entity can be visualized. + */ + public static boolean canVisualize(T blockEntity) { + return getVisualizer(blockEntity) != null; + } + + /** + * Checks if the given entity can be visualized. + * @param type The entity to check. + * @param The entity. + * @return {@code true} if the entity can be visualized. + */ + public static boolean canVisualize(T entity) { + return getVisualizer(entity) != null; + } + + /** + * Checks if the given block entity is visualized and should not be rendered normally. + * @param blockEntity The block entity to check. + * @param The type of the block entity. + * @return {@code true} if the block entity is visualized and should not be rendered normally. + */ + public static boolean shouldSkipRender(T blockEntity) { + BlockEntityVisualizer visualizer = getVisualizer(blockEntity); + if (visualizer == null) { + return false; + } + return visualizer.shouldSkipRender(blockEntity); + } + + /** + * Checks if the given entity is visualized and should not be rendered normally. + * @param entity The entity to check. + * @param The type of the entity. + * @return {@code true} if the entity is visualized and should not be rendered normally. + */ + public static boolean shouldSkipRender(T entity) { + EntityVisualizer visualizer = getVisualizer(entity); + if (visualizer == null) { + return false; + } + return visualizer.shouldSkipRender(entity); + } + + private VisualizationHelper() { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizedRenderDispatcher.java similarity index 53% rename from src/main/java/com/jozufozu/flywheel/impl/instancing/InstancedRenderDispatcher.java rename to src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizedRenderDispatcher.java index 11aaaabd3..208f15811 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/InstancedRenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualizedRenderDispatcher.java @@ -1,13 +1,13 @@ -package com.jozufozu.flywheel.impl.instancing; +package com.jozufozu.flywheel.impl.visualization; import java.util.List; import com.jozufozu.flywheel.api.event.BeginFrameEvent; 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.api.visual.Effect; +import com.jozufozu.flywheel.api.visual.Visual; import com.jozufozu.flywheel.extension.ClientLevelExtension; -import com.jozufozu.flywheel.impl.instancing.manager.InstanceManager; +import com.jozufozu.flywheel.impl.visualization.manager.VisualManager; import com.jozufozu.flywheel.lib.util.AnimationTickHolder; import com.jozufozu.flywheel.util.FlwUtil; import com.jozufozu.flywheel.util.WorldAttached; @@ -21,81 +21,81 @@ import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraftforge.event.TickEvent; -public class InstancedRenderDispatcher { - private static final WorldAttached INSTANCE_WORLDS = new WorldAttached<>(InstanceWorld::new); +public class VisualizedRenderDispatcher { + private static final WorldAttached VISUAL_WORLDS = new WorldAttached<>(VisualWorld::new); /** - * Call this when you want to run {@link Instance#update()}. - * @param blockEntity The block entity whose instance you want to update. + * Call this when you want to run {@link Visual#update()}. + * @param blockEntity The block entity whose visual you want to update. */ public static void queueUpdate(BlockEntity blockEntity) { if (!(blockEntity.getLevel() instanceof ClientLevel level)) { return; } - if (!FlwUtil.canUseInstancing(level)) { + if (!FlwUtil.canUseVisualization(level)) { return; } - INSTANCE_WORLDS.get(level) + VISUAL_WORLDS.get(level) .getBlockEntities() .queueUpdate(blockEntity); } /** - * Call this when you want to run {@link Instance#update()}. - * @param entity The entity whose instance you want to update. + * Call this when you want to run {@link Visual#update()}. + * @param entity The entity whose visual you want to update. */ public static void queueUpdate(Entity entity) { Level level = entity.level; - if (!FlwUtil.canUseInstancing(level)) { + if (!FlwUtil.canUseVisualization(level)) { return; } - INSTANCE_WORLDS.get(level) + VISUAL_WORLDS.get(level) .getEntities() .queueUpdate(entity); } /** - * Call this when you want to run {@link Instance#update()}. - * @param effect The effect whose instance you want to update. + * Call this when you want to run {@link Visual#update()}. + * @param effect The effect whose visual you want to update. */ public static void queueUpdate(LevelAccessor level, Effect effect) { - if (!FlwUtil.canUseInstancing(level)) { + if (!FlwUtil.canUseVisualization(level)) { return; } - INSTANCE_WORLDS.get(level) + VISUAL_WORLDS.get(level) .getEffects() .queueUpdate(effect); } /** - * Get or create the {@link InstanceWorld} for the given world. + * Get or create the {@link VisualWorld} for the given world. * @throws IllegalStateException if the backend is off */ - private static InstanceWorld getInstanceWorld(LevelAccessor level) { - if (!FlwUtil.canUseInstancing(level)) { - throw new IllegalStateException("Cannot retrieve instance world when backend is off!"); + private static VisualWorld getVisualWorld(LevelAccessor level) { + if (!FlwUtil.canUseVisualization(level)) { + throw new IllegalStateException("Cannot retrieve visual world when backend is off!"); } - return INSTANCE_WORLDS.get(level); + return VISUAL_WORLDS.get(level); } - public static InstanceManager getBlockEntities(LevelAccessor level) { - return getInstanceWorld(level).getBlockEntities(); + public static VisualManager getBlockEntities(LevelAccessor level) { + return getVisualWorld(level).getBlockEntities(); } - public static InstanceManager getEntities(LevelAccessor level) { - return getInstanceWorld(level).getEntities(); + public static VisualManager getEntities(LevelAccessor level) { + return getVisualWorld(level).getEntities(); } - public static InstanceManager getEffects(LevelAccessor level) { - return getInstanceWorld(level).getEffects(); + public static VisualManager getEffects(LevelAccessor level) { + return getVisualWorld(level).getEffects(); } public static Vec3i getRenderOrigin(LevelAccessor level) { - return getInstanceWorld(level).getEngine().renderOrigin(); + return getVisualWorld(level).getEngine().renderOrigin(); } public static void tick(TickEvent.ClientTickEvent event) { @@ -116,7 +116,7 @@ public class InstancedRenderDispatcher { } Level level = cameraEntity.level; - if (!FlwUtil.canUseInstancing(level)) { + if (!FlwUtil.canUseVisualization(level)) { return; } @@ -124,7 +124,7 @@ public class InstancedRenderDispatcher { double cameraY = cameraEntity.getEyeY(); double cameraZ = cameraEntity.getZ(); - INSTANCE_WORLDS.get(level).tick(cameraX, cameraY, cameraZ); + VISUAL_WORLDS.get(level).tick(cameraX, cameraY, cameraZ); } public static void onBeginFrame(BeginFrameEvent event) { @@ -133,30 +133,30 @@ public class InstancedRenderDispatcher { } ClientLevel level = event.getContext().level(); - if (!FlwUtil.canUseInstancing(level)) { + if (!FlwUtil.canUseVisualization(level)) { return; } - INSTANCE_WORLDS.get(level).beginFrame(event.getContext()); + VISUAL_WORLDS.get(level).beginFrame(event.getContext()); } public static void onRenderStage(RenderStageEvent event) { ClientLevel level = event.getContext().level(); - if (!FlwUtil.canUseInstancing(level)) { + if (!FlwUtil.canUseVisualization(level)) { return; } - INSTANCE_WORLDS.get(level).renderStage(event.getContext(), event.getStage()); + VISUAL_WORLDS.get(level).renderStage(event.getContext(), event.getStage()); } - public static void resetInstanceWorld(ClientLevel level) { - INSTANCE_WORLDS.remove(level, InstanceWorld::delete); + public static void resetVisualWorld(ClientLevel level) { + VISUAL_WORLDS.remove(level, VisualWorld::delete); - if (!FlwUtil.canUseInstancing(level)) { + if (!FlwUtil.canUseVisualization(level)) { return; } - InstanceWorld world = INSTANCE_WORLDS.get(level); + VisualWorld world = VISUAL_WORLDS.get(level); // Block entities are loaded while chunks are baked. // Entities are loaded with the level, so when chunks are reloaded they need to be re-added. ClientLevelExtension.getAllLoadedEntities(level) @@ -165,8 +165,8 @@ public class InstancedRenderDispatcher { public static void addDebugInfo(List info) { ClientLevel level = Minecraft.getInstance().level; - if (FlwUtil.canUseInstancing(level)) { - INSTANCE_WORLDS.get(level).addDebugInfo(info); + if (FlwUtil.canUseVisualization(level)) { + VISUAL_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/visualization/manager/BlockEntityVisualManager.java similarity index 55% rename from src/main/java/com/jozufozu/flywheel/impl/instancing/manager/BlockEntityInstanceManager.java rename to src/main/java/com/jozufozu/flywheel/impl/visualization/manager/BlockEntityVisualManager.java index cf4a7ba84..55d05edd4 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/manager/BlockEntityInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/BlockEntityVisualManager.java @@ -1,16 +1,16 @@ -package com.jozufozu.flywheel.impl.instancing.manager; +package com.jozufozu.flywheel.impl.visualization.manager; import java.util.List; import org.jetbrains.annotations.Nullable; 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.impl.instancing.InstancingControllerHelper; -import com.jozufozu.flywheel.impl.instancing.storage.One2OneStorage; -import com.jozufozu.flywheel.impl.instancing.storage.Storage; +import com.jozufozu.flywheel.api.visual.BlockEntityVisual; +import com.jozufozu.flywheel.api.visual.Visual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.impl.visualization.VisualizationHelper; +import com.jozufozu.flywheel.impl.visualization.storage.One2OneStorage; +import com.jozufozu.flywheel.impl.visualization.storage.Storage; import com.jozufozu.flywheel.util.FlwUtil; import it.unimi.dsi.fastutil.longs.Long2ObjectMap; @@ -20,10 +20,10 @@ import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; -public class BlockEntityInstanceManager extends InstanceManager { +public class BlockEntityVisualManager extends VisualManager { private final BlockEntityStorage storage; - public BlockEntityInstanceManager(Engine engine) { + public BlockEntityVisualManager(Engine engine) { storage = new BlockEntityStorage(engine); } @@ -32,15 +32,15 @@ public class BlockEntityInstanceManager extends InstanceManager { return storage; } - public void getCrumblingInstances(long pos, List> data) { - BlockEntityInstance instance = storage.posLookup.get(pos); - if (instance != null) { - data.add(instance); + public void getCrumblingVisuals(long pos, List> visuals) { + BlockEntityVisual visual = storage.posLookup.get(pos); + if (visual != null) { + visuals.add(visual); } } private static class BlockEntityStorage extends One2OneStorage { - private final Long2ObjectMap> posLookup = new Long2ObjectOpenHashMap<>(); + private final Long2ObjectMap> posLookup = new Long2ObjectOpenHashMap<>(); public BlockEntityStorage(Engine engine) { super(engine); @@ -52,7 +52,7 @@ public class BlockEntityInstanceManager extends InstanceManager { return false; } - if (!InstancingControllerHelper.canInstance(blockEntity)) { + if (!VisualizationHelper.canVisualize(blockEntity)) { return false; } @@ -79,18 +79,18 @@ public class BlockEntityInstanceManager extends InstanceManager { @Override @Nullable - protected Instance createRaw(BlockEntity obj) { - var controller = InstancingControllerHelper.getController(obj); - if (controller == null) { + protected Visual createRaw(BlockEntity obj) { + var visualizer = VisualizationHelper.getVisualizer(obj); + if (visualizer == null) { return null; } - var instance = controller.createInstance(new InstanceContext(engine, engine.renderOrigin()), obj); + var visual = visualizer.createVisual(new VisualizationContext(engine, engine.renderOrigin()), obj); BlockPos blockPos = obj.getBlockPos(); - posLookup.put(blockPos.asLong(), instance); + posLookup.put(blockPos.asLong(), visual); - return instance; + return visual; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/EffectVisualManager.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/EffectVisualManager.java new file mode 100644 index 000000000..179503246 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/EffectVisualManager.java @@ -0,0 +1,39 @@ +package com.jozufozu.flywheel.impl.visualization.manager; + +import java.util.Collection; + +import com.jozufozu.flywheel.api.backend.Engine; +import com.jozufozu.flywheel.api.visual.Effect; +import com.jozufozu.flywheel.api.visual.Visual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.impl.visualization.storage.One2ManyStorage; +import com.jozufozu.flywheel.impl.visualization.storage.Storage; + +public class EffectVisualManager extends VisualManager { + private final EffectStorage storage; + + public EffectVisualManager(Engine engine) { + storage = new EffectStorage(engine); + } + + @Override + protected Storage getStorage() { + return storage; + } + + private static class EffectStorage extends One2ManyStorage { + public EffectStorage(Engine engine) { + super(engine); + } + + @Override + protected Collection createRaw(Effect obj) { + return obj.createVisuals(new VisualizationContext(engine, engine.renderOrigin())); + } + + @Override + public boolean willAccept(Effect obj) { + return true; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/EntityVisualManager.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/EntityVisualManager.java new file mode 100644 index 000000000..99ea64839 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/EntityVisualManager.java @@ -0,0 +1,59 @@ +package com.jozufozu.flywheel.impl.visualization.manager; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.api.backend.Engine; +import com.jozufozu.flywheel.api.visual.Visual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.impl.visualization.VisualizationHelper; +import com.jozufozu.flywheel.impl.visualization.storage.One2OneStorage; +import com.jozufozu.flywheel.impl.visualization.storage.Storage; +import com.jozufozu.flywheel.util.FlwUtil; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.level.Level; + +public class EntityVisualManager extends VisualManager { + private final EntityStorage storage; + + public EntityVisualManager(Engine engine) { + storage = new EntityStorage(engine); + } + + @Override + protected Storage getStorage() { + return storage; + } + + private static class EntityStorage extends One2OneStorage { + public EntityStorage(Engine engine) { + super(engine); + } + + @Override + @Nullable + protected Visual createRaw(Entity obj) { + var visualizer = VisualizationHelper.getVisualizer(obj); + if (visualizer == null) { + return null; + } + + return visualizer.createVisual(new VisualizationContext(engine, engine.renderOrigin()), obj); + } + + @Override + public boolean willAccept(Entity entity) { + if (!entity.isAlive()) { + return false; + } + + if (!VisualizationHelper.canVisualize(entity)) { + return false; + } + + Level level = entity.level; + + return FlwUtil.isFlywheelLevel(level); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/VisualManager.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/VisualManager.java new file mode 100644 index 000000000..1febcea8c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/manager/VisualManager.java @@ -0,0 +1,173 @@ +package com.jozufozu.flywheel.impl.visualization.manager; + +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.function.Consumer; + +import org.joml.FrustumIntersection; + +import com.jozufozu.flywheel.api.task.TaskExecutor; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visual.TickableVisual; +import com.jozufozu.flywheel.api.visual.Visual; +import com.jozufozu.flywheel.config.FlwConfig; +import com.jozufozu.flywheel.impl.visualization.ratelimit.BandedPrimeLimiter; +import com.jozufozu.flywheel.impl.visualization.ratelimit.DistanceUpdateLimiter; +import com.jozufozu.flywheel.impl.visualization.ratelimit.NonLimiter; +import com.jozufozu.flywheel.impl.visualization.storage.Storage; +import com.jozufozu.flywheel.impl.visualization.storage.Transaction; + +public abstract class VisualManager { + private final Queue> queue = new ConcurrentLinkedQueue<>(); + + protected DistanceUpdateLimiter tickLimiter; + protected DistanceUpdateLimiter frameLimiter; + + public VisualManager() { + tickLimiter = createUpdateLimiter(); + frameLimiter = createUpdateLimiter(); + } + + protected abstract Storage getStorage(); + + protected DistanceUpdateLimiter createUpdateLimiter() { + if (FlwConfig.get().limitUpdates()) { + return new BandedPrimeLimiter(); + } else { + return new NonLimiter(); + } + } + + /** + * Get the number of game objects that are currently being visualized. + * + * @return The object count. + */ + public int getVisualCount() { + return getStorage().getAllVisuals().size(); + } + + public void add(T obj) { + if (!getStorage().willAccept(obj)) { + return; + } + + getStorage().add(obj); + } + + public void queueAdd(T obj) { + if (!getStorage().willAccept(obj)) { + return; + } + + 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 visual associated with an object. + * + *

+ * By default this is the only hook a {@link Visual} has to change its internal state. This is the lowest frequency + * update hook {@link Visual} gets. For more frequent updates, see {@link TickableVisual} and + * {@link DynamicVisual}. + *

+ * + * @param obj the object whose visual will be updated. + */ + public void update(T obj) { + if (!getStorage().willAccept(obj)) { + return; + } + + getStorage().update(obj); + } + + public void queueUpdate(T obj) { + if (!getStorage().willAccept(obj)) { + return; + } + + queue.add(Transaction.update(obj)); + } + + public void recreateAll() { + getStorage().recreateAll(); + } + + public void invalidate() { + getStorage().invalidate(); + } + + protected void processQueue() { + var storage = getStorage(); + Transaction transaction; + while ((transaction = queue.poll()) != null) { + transaction.apply(storage); + } + } + + /** + * Ticks the VisualManager. + * + *

+ * {@link TickableVisual}s get ticked. + *
+ * Queued updates are processed. + *

+ */ + public void tick(TaskExecutor executor, double cameraX, double cameraY, double cameraZ) { + tickLimiter.tick(); + processQueue(); + + var visuals = getStorage().getTickableVisuals(); + distributeWork(executor, visuals, visual -> tickVisual(visual, cameraX, cameraY, cameraZ)); + } + + protected void tickVisual(TickableVisual visual, double cameraX, double cameraY, double cameraZ) { + if (!visual.decreaseTickRateWithDistance() || tickLimiter.shouldUpdate(visual.distanceSquared(cameraX, cameraY, cameraZ))) { + visual.tick(); + } + } + + public void beginFrame(TaskExecutor executor, double cameraX, double cameraY, double cameraZ, FrustumIntersection frustum) { + frameLimiter.tick(); + processQueue(); + + var visuals = getStorage().getDynamicVisuals(); + distributeWork(executor, visuals, visual -> updateVisual(visual, cameraX, cameraY, cameraZ, frustum)); + } + + protected void updateVisual(DynamicVisual visual, double cameraX, double cameraY, double cameraZ, FrustumIntersection frustum) { + if (!visual.decreaseFramerateWithDistance() || frameLimiter.shouldUpdate(visual.distanceSquared(cameraX, cameraY, cameraZ))) { + if (visual.isVisible(frustum)) { + visual.beginFrame(); + } + } + } + + private static void distributeWork(TaskExecutor executor, List visuals, Consumer action) { + final int amount = visuals.size(); + final int threadCount = executor.getThreadCount(); + + if (threadCount == 1) { + executor.execute(() -> visuals.forEach(action)); + } else { + final int stride = Math.max(amount / (threadCount * 2), 1); + for (int start = 0; start < amount; start += stride) { + int end = Math.min(start + stride, amount); + + var sub = visuals.subList(start, end); + executor.execute(() -> sub.forEach(action)); + } + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/BandedPrimeLimiter.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/BandedPrimeLimiter.java similarity index 91% rename from src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/BandedPrimeLimiter.java rename to src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/BandedPrimeLimiter.java index 3b58e4e09..f311ccc09 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/BandedPrimeLimiter.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/BandedPrimeLimiter.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.impl.instancing.ratelimit; +package com.jozufozu.flywheel.impl.visualization.ratelimit; import net.minecraft.util.Mth; diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/DistanceUpdateLimiter.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/DistanceUpdateLimiter.java similarity index 88% rename from src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/DistanceUpdateLimiter.java rename to src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/DistanceUpdateLimiter.java index 127e2ce6a..d2217b734 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/DistanceUpdateLimiter.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/DistanceUpdateLimiter.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.impl.instancing.ratelimit; +package com.jozufozu.flywheel.impl.visualization.ratelimit; /** * Interface for rate-limiting updates based on an object's distance from the camera. diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/NonLimiter.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/NonLimiter.java similarity index 75% rename from src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/NonLimiter.java rename to src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/NonLimiter.java index 807005e73..c0d77d88a 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/ratelimit/NonLimiter.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/ratelimit/NonLimiter.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.impl.instancing.ratelimit; +package com.jozufozu.flywheel.impl.visualization.ratelimit; public class NonLimiter implements DistanceUpdateLimiter { @Override diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/AbstractStorage.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/AbstractStorage.java new file mode 100644 index 000000000..9ed40982e --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/AbstractStorage.java @@ -0,0 +1,43 @@ +package com.jozufozu.flywheel.impl.visualization.storage; + +import java.util.ArrayList; +import java.util.List; + +import com.jozufozu.flywheel.api.backend.Engine; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visual.TickableVisual; +import com.jozufozu.flywheel.api.visual.Visual; + +public abstract class AbstractStorage implements Storage { + protected final Engine engine; + protected final List tickableVisuals = new ArrayList<>(); + protected final List dynamicVisuals = new ArrayList<>(); + + protected AbstractStorage(Engine engine) { + this.engine = engine; + } + + @Override + public List getTickableVisuals() { + return tickableVisuals; + } + + @Override + public List getDynamicVisuals() { + return dynamicVisuals; + } + + protected void setup(Visual visual) { + visual.init(); + + if (visual instanceof TickableVisual tickable) { + tickableVisuals.add(tickable); + tickable.tick(); + } + + if (visual instanceof DynamicVisual dynamic) { + dynamicVisuals.add(dynamic); + dynamic.beginFrame(); + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Action.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Action.java new file mode 100644 index 000000000..aa54498e8 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Action.java @@ -0,0 +1,7 @@ +package com.jozufozu.flywheel.impl.visualization.storage; + +public enum Action { + ADD, + REMOVE, + UPDATE, +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/One2ManyStorage.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/One2ManyStorage.java new file mode 100644 index 000000000..367bc50bc --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/One2ManyStorage.java @@ -0,0 +1,86 @@ +package com.jozufozu.flywheel.impl.visualization.storage; + +import java.util.Collection; +import java.util.List; + +import com.google.common.collect.HashMultimap; +import com.google.common.collect.Multimap; +import com.jozufozu.flywheel.api.backend.Engine; +import com.jozufozu.flywheel.api.visual.Visual; + +public abstract class One2ManyStorage extends AbstractStorage { + private final Multimap allVisuals = HashMultimap.create(); + + public One2ManyStorage(Engine engine) { + super(engine); + } + + @Override + public Collection getAllVisuals() { + return allVisuals.values(); + } + + @Override + public void add(T obj) { + Collection visuals = allVisuals.get(obj); + + if (visuals.isEmpty()) { + create(obj); + } + } + + @Override + public void remove(T obj) { + Collection visuals = allVisuals.removeAll(obj); + + if (visuals.isEmpty()) { + return; + } + + tickableVisuals.removeAll(visuals); + dynamicVisuals.removeAll(visuals); + visuals.forEach(Visual::delete); + } + + @Override + public void update(T obj) { + Collection visuals = allVisuals.get(obj); + + if (visuals.isEmpty()) { + return; + } + + // TODO: shouldReset cannot be checked here because all visuals are created at once + visuals.forEach(Visual::update); + } + + @Override + public void recreateAll() { + tickableVisuals.clear(); + dynamicVisuals.clear(); + allVisuals.values().forEach(Visual::delete); + + List objects = List.copyOf(allVisuals.keySet()); + allVisuals.clear(); + objects.forEach(this::create); + } + + @Override + public void invalidate() { + tickableVisuals.clear(); + dynamicVisuals.clear(); + allVisuals.values().forEach(Visual::delete); + allVisuals.clear(); + } + + private void create(T obj) { + Collection visuals = createRaw(obj); + + if (!visuals.isEmpty()) { + visuals.forEach(this::setup); + allVisuals.putAll(obj, visuals); + } + } + + protected abstract Collection createRaw(T obj); +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/One2OneStorage.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/One2OneStorage.java new file mode 100644 index 000000000..ab5efb06d --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/One2OneStorage.java @@ -0,0 +1,101 @@ +package com.jozufozu.flywheel.impl.visualization.storage; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +import org.jetbrains.annotations.Nullable; + +import com.jozufozu.flywheel.api.backend.Engine; +import com.jozufozu.flywheel.api.visual.Visual; + +public abstract class One2OneStorage extends AbstractStorage { + private final Map visuals = new HashMap<>(); + + public One2OneStorage(Engine engine) { + super(engine); + } + + @Override + public Collection getAllVisuals() { + return visuals.values(); + } + + @Override + public void add(T obj) { + Visual visual = visuals.get(obj); + + if (visual == null) { + create(obj); + } + } + + @Override + public void remove(T obj) { + Visual visual = visuals.remove(obj); + + if (visual == null) { + return; + } + + tickableVisuals.remove(visual); + dynamicVisuals.remove(visual); + visual.delete(); + } + + @Override + public void update(T obj) { + Visual visual = visuals.get(obj); + + if (visual == null) { + return; + } + + // resetting visuals is by default used to handle block state changes. + if (visual.shouldReset()) { + // delete and re-create the visual. + // resetting a visual supersedes updating it. + remove(obj); + create(obj); + } else { + visual.update(); + } + } + + @Override + public void recreateAll() { + tickableVisuals.clear(); + dynamicVisuals.clear(); + visuals.replaceAll((obj, visual) -> { + visual.delete(); + + Visual out = createRaw(obj); + + if (out != null) { + setup(out); + } + + return out; + }); + } + + @Override + public void invalidate() { + tickableVisuals.clear(); + dynamicVisuals.clear(); + visuals.values().forEach(Visual::delete); + visuals.clear(); + } + + private void create(T obj) { + Visual visual = createRaw(obj); + + if (visual != null) { + setup(visual); + visuals.put(obj, visual); + } + } + + @Nullable + protected abstract Visual createRaw(T obj); +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Storage.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Storage.java new file mode 100644 index 000000000..001ac7293 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Storage.java @@ -0,0 +1,33 @@ +package com.jozufozu.flywheel.impl.visualization.storage; + +import java.util.Collection; +import java.util.List; + +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visual.TickableVisual; +import com.jozufozu.flywheel.api.visual.Visual; + +public interface Storage { + Collection getAllVisuals(); + + List getTickableVisuals(); + + List getDynamicVisuals(); + + /** + * Is the given object currently capable of being added? + * + * @return true if the object is currently capable of being visualized. + */ + boolean willAccept(T obj); + + void add(T obj); + + void remove(T obj); + + void update(T obj); + + void recreateAll(); + + void invalidate(); +} diff --git a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Transaction.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Transaction.java similarity index 90% rename from src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Transaction.java rename to src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Transaction.java index fb127515c..f7526e3b9 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/instancing/storage/Transaction.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/storage/Transaction.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.impl.instancing.storage; +package com.jozufozu.flywheel.impl.visualization.storage; public record Transaction(T obj, Action action) { public static Transaction add(T obj) { diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java index bc9ed00a9..a4d17b1ec 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java @@ -1,93 +1,28 @@ package com.jozufozu.flywheel.lib.instance; -import java.util.stream.Stream; - import com.jozufozu.flywheel.api.instance.Instance; -import com.jozufozu.flywheel.api.instance.controller.InstanceContext; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; -import com.jozufozu.flywheel.lib.light.LightListener; -import com.jozufozu.flywheel.lib.light.LightUpdater; -import com.jozufozu.flywheel.lib.struct.FlatLit; +import com.jozufozu.flywheel.api.instance.InstanceHandle; +import com.jozufozu.flywheel.api.instance.InstanceType; -import net.minecraft.core.BlockPos; -import net.minecraft.core.SectionPos; -import net.minecraft.core.Vec3i; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LightLayer; +public abstract class AbstractInstance implements Instance { + protected final InstanceType type; + protected final InstanceHandle handle; -public abstract class AbstractInstance implements Instance, LightListener { - protected final InstancerProvider instancerProvider; - protected final Vec3i renderOrigin; - protected final Level level; - - protected boolean deleted = false; - - public AbstractInstance(InstanceContext ctx, Level level) { - this.instancerProvider = ctx.instancerProvider(); - this.renderOrigin = ctx.renderOrigin(); - this.level = level; + protected AbstractInstance(InstanceType type, InstanceHandle handle) { + this.type = type; + this.handle = handle; } @Override - public void init() { - LightUpdater.get(level).addListener(this); - updateLight(); + public InstanceType type() { + return type; } - @Override - public void update() { + public final void setChanged() { + handle.setChanged(); } - @Override - public boolean shouldReset() { - return false; - } - - /** - * Called after construction and when a light update occurs in the world. - * - *
If your model needs it, update light here. - */ - public void updateLight() { - } - - protected abstract void _delete(); - - @Override public final void delete() { - if (deleted) { - return; - } - - _delete(); - deleted = true; - } - - @Override - public void onLightUpdate(LightLayer type, SectionPos pos) { - updateLight(); - } - - @Override - public boolean isInvalid() { - return deleted; - } - - protected void relight(BlockPos pos, FlatLit... parts) { - relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), parts); - } - - protected void relight(int block, int sky, FlatLit... parts) { - for (FlatLit part : parts) { - part.setLight(block, sky); - } - } - - protected > void relight(BlockPos pos, Stream parts) { - relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), parts); - } - - protected > void relight(int block, int sky, Stream parts) { - parts.forEach(model -> model.setLight(block, sky)); + handle.setDeleted(); } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitPart.java b/src/main/java/com/jozufozu/flywheel/lib/instance/ColoredLitInstance.java similarity index 56% rename from src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitPart.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/ColoredLitInstance.java index b92815f7e..d3a407a02 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitPart.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/ColoredLitInstance.java @@ -1,11 +1,11 @@ -package com.jozufozu.flywheel.lib.struct; +package com.jozufozu.flywheel.lib.instance; -import com.jozufozu.flywheel.api.struct.Handle; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.InstanceHandle; +import com.jozufozu.flywheel.api.instance.InstanceType; import net.minecraft.client.renderer.LightTexture; -public abstract class ColoredLitPart extends AbstractInstancePart implements FlatLit { +public abstract class ColoredLitInstance extends AbstractInstance implements FlatLit { public byte blockLight; public byte skyLight; @@ -14,19 +14,19 @@ 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 ColoredLitInstance(InstanceType type, InstanceHandle handle) { super(type, handle); } @Override - public ColoredLitPart setBlockLight(int blockLight) { + public ColoredLitInstance setBlockLight(int blockLight) { this.blockLight = (byte) blockLight; setChanged(); return this; } @Override - public ColoredLitPart setSkyLight(int skyLight) { + public ColoredLitInstance setSkyLight(int skyLight) { this.skyLight = (byte) skyLight; setChanged(); return this; @@ -37,11 +37,11 @@ public abstract class ColoredLitPart extends AbstractInstancePart implements Fla return LightTexture.pack(blockLight, skyLight); } - public ColoredLitPart setColor(int color) { + public ColoredLitInstance setColor(int color) { return setColor(color, false); } - public ColoredLitPart setColor(int color, boolean alpha) { + public ColoredLitInstance setColor(int color, boolean alpha) { byte r = (byte) ((color >> 16) & 0xFF); byte g = (byte) ((color >> 8) & 0xFF); byte b = (byte) (color & 0xFF); @@ -54,11 +54,11 @@ public abstract class ColoredLitPart extends AbstractInstancePart implements Fla } } - public ColoredLitPart setColor(int r, int g, int b) { + public ColoredLitInstance setColor(int r, int g, int b) { return setColor((byte) r, (byte) g, (byte) b); } - public ColoredLitPart setColor(byte r, byte g, byte b) { + public ColoredLitInstance setColor(byte r, byte g, byte b) { this.r = r; this.g = g; this.b = b; @@ -66,7 +66,7 @@ public abstract class ColoredLitPart extends AbstractInstancePart implements Fla return this; } - public ColoredLitPart setColor(byte r, byte g, byte b, byte a) { + public ColoredLitInstance setColor(byte r, byte g, byte b, byte a) { this.r = r; this.g = g; this.b = b; diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/ColoredLitWriter.java b/src/main/java/com/jozufozu/flywheel/lib/instance/ColoredLitWriter.java new file mode 100644 index 000000000..1b9d612e7 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/ColoredLitWriter.java @@ -0,0 +1,17 @@ +package com.jozufozu.flywheel.lib.instance; + +import org.lwjgl.system.MemoryUtil; + +import com.jozufozu.flywheel.api.instance.InstanceWriter; + +public abstract class ColoredLitWriter implements InstanceWriter { + @Override + public void write(final long ptr, final I instance) { + MemoryUtil.memPutShort(ptr, instance.blockLight); + MemoryUtil.memPutShort(ptr + 2, instance.skyLight); + MemoryUtil.memPutByte(ptr + 4, instance.r); + MemoryUtil.memPutByte(ptr + 5, instance.g); + MemoryUtil.memPutByte(ptr + 6, instance.b); + MemoryUtil.memPutByte(ptr + 7, instance.a); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/FlatLit.java b/src/main/java/com/jozufozu/flywheel/lib/instance/FlatLit.java similarity index 63% rename from src/main/java/com/jozufozu/flywheel/lib/struct/FlatLit.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/FlatLit.java index ae23de706..17d81b96b 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/FlatLit.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/FlatLit.java @@ -1,39 +1,39 @@ -package com.jozufozu.flywheel.lib.struct; +package com.jozufozu.flywheel.lib.instance; -import com.jozufozu.flywheel.api.struct.InstancePart; +import com.jozufozu.flywheel.api.instance.Instance; import net.minecraft.core.BlockPos; import net.minecraft.world.level.BlockAndTintGetter; import net.minecraft.world.level.LightLayer; /** - * An interface that implementors of {@link InstancePart} should also implement + * An interface that implementors of {@link Instance} should also implement * if they wish to make use of Flywheel's provided light update methods. *

* This only covers flat lighting, smooth lighting is still TODO. * - * @param

The name of the class that implements this interface. + * @param The name of the class that implements this interface. */ -public interface FlatLit

> { +public interface FlatLit> { /** * @param blockLight An integer in the range [0, 15] representing the * amount of block light this instance should receive. * @return {@code this} */ - P setBlockLight(int blockLight); + I setBlockLight(int blockLight); /** * @param skyLight An integer in the range [0, 15] representing the * amount of sky light this instance should receive. * @return {@code this} */ - P setSkyLight(int skyLight); + I setSkyLight(int skyLight); - default P setLight(int blockLight, int skyLight) { + default I setLight(int blockLight, int skyLight) { return setBlockLight(blockLight).setSkyLight(skyLight); } - default P updateLight(BlockAndTintGetter level, BlockPos pos) { + default I updateLight(BlockAndTintGetter level, BlockPos pos) { return setLight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos)); } diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/StructTypes.java b/src/main/java/com/jozufozu/flywheel/lib/instance/InstanceTypes.java similarity index 64% rename from src/main/java/com/jozufozu/flywheel/lib/struct/StructTypes.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/InstanceTypes.java index f42b02b9f..795f8853b 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/StructTypes.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/InstanceTypes.java @@ -1,16 +1,16 @@ -package com.jozufozu.flywheel.lib.struct; +package com.jozufozu.flywheel.lib.instance; import org.jetbrains.annotations.ApiStatus; import com.jozufozu.flywheel.Flywheel; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.util.ResourceUtil; import net.minecraft.resources.ResourceLocation; -public final class StructTypes { - public static final StructType TRANSFORMED = StructType.REGISTRY.registerAndGet(new TransformedType()); - public static final StructType ORIENTED = StructType.REGISTRY.registerAndGet(new OrientedType()); +public final class InstanceTypes { + public static final InstanceType TRANSFORMED = InstanceType.REGISTRY.registerAndGet(new TransformedType()); + public static final InstanceType ORIENTED = InstanceType.REGISTRY.registerAndGet(new OrientedType()); @ApiStatus.Internal public static void init() { diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedPart.java b/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedInstance.java similarity index 60% rename from src/main/java/com/jozufozu/flywheel/lib/struct/OrientedPart.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/OrientedInstance.java index c8589fd3b..519a7e637 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedPart.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedInstance.java @@ -1,13 +1,13 @@ -package com.jozufozu.flywheel.lib.struct; +package com.jozufozu.flywheel.lib.instance; -import com.jozufozu.flywheel.api.struct.Handle; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.InstanceHandle; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; import net.minecraft.core.BlockPos; -public class OrientedPart extends ColoredLitPart { +public class OrientedInstance extends ColoredLitInstance { public float posX; public float posY; public float posZ; @@ -19,19 +19,19 @@ public class OrientedPart extends ColoredLitPart { public float qZ; public float qW = 1; - public OrientedPart(StructType type, Handle handle) { + public OrientedInstance(InstanceType type, InstanceHandle handle) { super(type, handle); } - public OrientedPart setPosition(BlockPos pos) { + public OrientedInstance setPosition(BlockPos pos) { return setPosition(pos.getX(), pos.getY(), pos.getZ()); } - public OrientedPart setPosition(Vector3f pos) { + public OrientedInstance setPosition(Vector3f pos) { return setPosition(pos.x(), pos.y(), pos.z()); } - public OrientedPart setPosition(float x, float y, float z) { + public OrientedInstance setPosition(float x, float y, float z) { this.posX = x; this.posY = y; this.posZ = z; @@ -39,7 +39,7 @@ public class OrientedPart extends ColoredLitPart { return this; } - public OrientedPart nudge(float x, float y, float z) { + public OrientedInstance nudge(float x, float y, float z) { this.posX += x; this.posY += y; this.posZ += z; @@ -47,15 +47,15 @@ public class OrientedPart extends ColoredLitPart { return this; } - public OrientedPart setPivot(Vector3f pos) { + public OrientedInstance setPivot(Vector3f pos) { return setPosition(pos.x(), pos.y(), pos.z()); } - public OrientedPart setPivot(net.minecraft.world.phys.Vec3 pos) { + public OrientedInstance setPivot(net.minecraft.world.phys.Vec3 pos) { return setPosition((float) pos.x(), (float) pos.y(), (float) pos.z()); } - public OrientedPart setPivot(float x, float y, float z) { + public OrientedInstance setPivot(float x, float y, float z) { this.pivotX = x; this.pivotY = y; this.pivotZ = z; @@ -63,11 +63,11 @@ public class OrientedPart extends ColoredLitPart { return this; } - public OrientedPart setRotation(Quaternion q) { + public OrientedInstance setRotation(Quaternion q) { return setRotation(q.i(), q.j(), q.k(), q.r()); } - public OrientedPart setRotation(float x, float y, float z, float w) { + public OrientedInstance setRotation(float x, float y, float z, float w) { this.qX = x; this.qY = y; this.qZ = z; @@ -76,7 +76,7 @@ public class OrientedPart extends ColoredLitPart { return this; } - public OrientedPart resetRotation() { + public OrientedInstance resetRotation() { this.qX = 0; this.qY = 0; this.qZ = 0; @@ -86,8 +86,8 @@ public class OrientedPart extends ColoredLitPart { } @Override - public OrientedPart copy(Handle handle) { - var out = StructTypes.ORIENTED.create(handle); + public OrientedInstance copy(InstanceHandle handle) { + var out = InstanceTypes.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/instance/OrientedType.java similarity index 53% rename from src/main/java/com/jozufozu/flywheel/lib/struct/OrientedType.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/OrientedType.java index ae0317fbd..722b42897 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedType.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedType.java @@ -1,10 +1,10 @@ -package com.jozufozu.flywheel.lib.struct; +package com.jozufozu.flywheel.lib.instance; +import com.jozufozu.flywheel.api.instance.InstanceHandle; +import com.jozufozu.flywheel.api.instance.InstanceType; +import com.jozufozu.flywheel.api.instance.InstanceVertexTransformer; +import com.jozufozu.flywheel.api.instance.InstanceWriter; 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.lib.math.RenderMath; import com.jozufozu.flywheel.lib.vertex.VertexTransformations; @@ -14,7 +14,7 @@ import com.mojang.math.Quaternion; import net.minecraft.resources.ResourceLocation; -public class OrientedType implements StructType { +public class OrientedType implements InstanceType { public static final BufferLayout FORMAT = BufferLayout.builder() .addItem(CommonItems.LIGHT_COORD, "light") .addItem(CommonItems.UNORM_4x8, "color") @@ -24,8 +24,8 @@ public class OrientedType implements StructType { .build(); @Override - public OrientedPart create(Handle handle) { - return new OrientedPart(this, handle); + public OrientedInstance create(InstanceHandle handle) { + return new OrientedInstance(this, handle); } @Override @@ -34,33 +34,33 @@ public class OrientedType implements StructType { } @Override - public StructWriter getWriter() { + public InstanceWriter getWriter() { return OrientedWriter.INSTANCE; } @Override public ResourceLocation instanceShader() { - return StructTypes.Files.ORIENTED; + return InstanceTypes.Files.ORIENTED; } @Override - public StructVertexTransformer getVertexTransformer() { - return (vertexList, struct, level) -> { - Quaternion q = new Quaternion(struct.qX, struct.qY, struct.qZ, struct.qW); + public InstanceVertexTransformer getVertexTransformer() { + return (vertexList, instance, level) -> { + Quaternion q = new Quaternion(instance.qX, instance.qY, instance.qZ, instance.qW); Matrix4f modelMatrix = new Matrix4f(); modelMatrix.setIdentity(); - modelMatrix.multiplyWithTranslation(struct.posX + struct.pivotX, struct.posY + struct.pivotY, struct.posZ + struct.pivotZ); + modelMatrix.multiplyWithTranslation(instance.posX + instance.pivotX, instance.posY + instance.pivotY, instance.posZ + instance.pivotZ); modelMatrix.multiply(q); - modelMatrix.multiplyWithTranslation(-struct.pivotX, -struct.pivotY, -struct.pivotZ); + modelMatrix.multiplyWithTranslation(-instance.pivotX, -instance.pivotY, -instance.pivotZ); Matrix3f normalMatrix = new Matrix3f(q); - float r = RenderMath.uf(struct.r); - float g = RenderMath.uf(struct.g); - float b = RenderMath.uf(struct.b); - float a = RenderMath.uf(struct.a); - int light = struct.getPackedLight(); + float r = RenderMath.uf(instance.r); + float g = RenderMath.uf(instance.g); + float b = RenderMath.uf(instance.b); + float a = RenderMath.uf(instance.a); + int light = instance.getPackedLight(); for (int i = 0; i < vertexList.vertexCount(); i++) { VertexTransformations.transformPos(vertexList, i, modelMatrix); diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedWriter.java b/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedWriter.java new file mode 100644 index 000000000..1e463b480 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/OrientedWriter.java @@ -0,0 +1,24 @@ +package com.jozufozu.flywheel.lib.instance; + +import org.lwjgl.system.MemoryUtil; + +public class OrientedWriter extends ColoredLitWriter { + public static final OrientedWriter INSTANCE = new OrientedWriter(); + + @Override + public void write(long ptr, OrientedInstance instance) { + super.write(ptr, instance); + + MemoryUtil.memPutFloat(ptr + 8, instance.posX); + MemoryUtil.memPutFloat(ptr + 12, instance.posY); + MemoryUtil.memPutFloat(ptr + 16, instance.posZ); + MemoryUtil.memPutFloat(ptr + 20, instance.pivotX); + MemoryUtil.memPutFloat(ptr + 24, instance.pivotY); + MemoryUtil.memPutFloat(ptr + 28, instance.pivotZ); + MemoryUtil.memPutFloat(ptr + 32, instance.qX); + MemoryUtil.memPutFloat(ptr + 36, instance.qY); + MemoryUtil.memPutFloat(ptr + 40, instance.qZ); + MemoryUtil.memPutFloat(ptr + 44, instance.qW); + } + +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java deleted file mode 100644 index 3fc0f4127..000000000 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.jozufozu.flywheel.lib.instance; - -import java.util.Objects; -import java.util.function.Predicate; - -import org.jetbrains.annotations.NotNull; - -import com.jozufozu.flywheel.api.instance.BlockEntityInstance; -import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; -import com.jozufozu.flywheel.api.instance.controller.InstanceContext; -import com.jozufozu.flywheel.api.instance.controller.InstancingControllerRegistry; - -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; - -public class SimpleBlockEntityInstancingController implements BlockEntityInstancingController { - protected Factory instanceFactory; - protected Predicate skipRender; - - public SimpleBlockEntityInstancingController(Factory instanceFactory, Predicate skipRender) { - this.instanceFactory = instanceFactory; - this.skipRender = skipRender; - } - - @Override - public BlockEntityInstance createInstance(InstanceContext ctx, T blockEntity) { - return instanceFactory.create(ctx, blockEntity); - } - - @Override - public boolean shouldSkipRender(T blockEntity) { - return skipRender.test(blockEntity); - } - - /** - * Get an object to configure the instancing controller for the given block entity type. - * - * @param type The block entity type to configure. - * @param The type of the block entity. - * @return The configuration object. - */ - public static BlockEntityConfig configure(BlockEntityType type) { - return new BlockEntityConfig<>(type); - } - - @FunctionalInterface - public interface Factory { - @NotNull BlockEntityInstance create(InstanceContext ctx, T blockEntity); - } - - /** - * An object to configure the instancing controller for a block entity. - * - * @param The type of the block entity. - */ - public static class BlockEntityConfig { - protected BlockEntityType type; - protected Factory instanceFactory; - protected Predicate skipRender; - - public BlockEntityConfig(BlockEntityType type) { - this.type = type; - } - - /** - * Sets the instance factory for the block entity. - * - * @param instanceFactory The instance factory. - * @return {@code this} - */ - public BlockEntityConfig factory(Factory instanceFactory) { - this.instanceFactory = instanceFactory; - return this; - } - - /** - * Sets a predicate to determine whether to skip rendering a block entity. - * @param skipRender The predicate. - * @return {@code this} - */ - public BlockEntityConfig skipRender(Predicate skipRender) { - this.skipRender = skipRender; - return this; - } - - /** - * Sets a predicate to always skip rendering for block entities of this type. - * @return {@code this} - */ - public BlockEntityConfig alwaysSkipRender() { - this.skipRender = be -> true; - return this; - } - - /** - * Constructs the block entity instancing controller, and sets it for the block entity type. - * @return The block entity instancing controller. - */ - public SimpleBlockEntityInstancingController apply() { - Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!"); - if (skipRender == null) { - skipRender = be -> false; - } - SimpleBlockEntityInstancingController controller = new SimpleBlockEntityInstancingController<>(instanceFactory, skipRender); - InstancingControllerRegistry.setController(type, controller); - return controller; - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java deleted file mode 100644 index b8256bb54..000000000 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java +++ /dev/null @@ -1,109 +0,0 @@ -package com.jozufozu.flywheel.lib.instance; - -import java.util.Objects; -import java.util.function.Predicate; - -import org.jetbrains.annotations.NotNull; - -import com.jozufozu.flywheel.api.instance.EntityInstance; -import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; -import com.jozufozu.flywheel.api.instance.controller.InstanceContext; -import com.jozufozu.flywheel.api.instance.controller.InstancingControllerRegistry; - -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; - -public class SimpleEntityInstancingController implements EntityInstancingController { - protected Factory instanceFactory; - protected Predicate skipRender; - - public SimpleEntityInstancingController(Factory instanceFactory, Predicate skipRender) { - this.instanceFactory = instanceFactory; - this.skipRender = skipRender; - } - - @Override - public EntityInstance createInstance(InstanceContext ctx, T entity) { - return instanceFactory.create(ctx, entity); - } - - @Override - public boolean shouldSkipRender(T entity) { - return skipRender.test(entity); - } - - /** - * Get an object to configure the instancing controller for the given entity type. - * - * @param type The entity type to configure. - * @param The type of the entity. - * @return The configuration object. - */ - public static EntityConfig configure(EntityType type) { - return new EntityConfig<>(type); - } - - @FunctionalInterface - public interface Factory { - @NotNull EntityInstance create(InstanceContext ctx, T entity); - } - - /** - * An object to configure the instancing controller for an entity. - * - * @param The type of the entity. - */ - public static class EntityConfig { - protected EntityType type; - protected Factory instanceFactory; - protected Predicate skipRender; - - public EntityConfig(EntityType type) { - this.type = type; - } - - /** - * Sets the instance factory for the entity. - * - * @param instanceFactory The instance factory. - * @return {@code this} - */ - public EntityConfig factory(Factory instanceFactory) { - this.instanceFactory = instanceFactory; - return this; - } - - /** - * Sets a predicate to determine whether to skip rendering an entity. - * @param skipRender The predicate. - * @return {@code this} - */ - public EntityConfig skipRender(Predicate skipRender) { - this.skipRender = skipRender; - return this; - } - - /** - * Sets a predicate to always skip rendering for entities of this type. - * @return {@code this} - */ - public EntityConfig alwaysSkipRender() { - this.skipRender = entity -> true; - return this; - } - - /** - * Constructs the entity instancing controller, and sets it for the entity type. - * @return The entity instancing controller. - */ - public SimpleEntityInstancingController apply() { - Objects.requireNonNull(instanceFactory, "Instance factory cannot be null!"); - if (skipRender == null) { - skipRender = entity -> false; - } - SimpleEntityInstancingController controller = new SimpleEntityInstancingController<>(instanceFactory, skipRender); - InstancingControllerRegistry.setController(type, controller); - return controller; - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedPart.java b/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedInstance.java similarity index 68% rename from src/main/java/com/jozufozu/flywheel/lib/struct/TransformedPart.java rename to src/main/java/com/jozufozu/flywheel/lib/instance/TransformedInstance.java index 90f1bb519..8e14bc299 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedPart.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedInstance.java @@ -1,7 +1,7 @@ -package com.jozufozu.flywheel.lib.struct; +package com.jozufozu.flywheel.lib.instance; -import com.jozufozu.flywheel.api.struct.Handle; -import com.jozufozu.flywheel.api.struct.StructType; +import com.jozufozu.flywheel.api.instance.InstanceHandle; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.lib.transform.Transform; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix3f; @@ -10,18 +10,18 @@ import com.mojang.math.Quaternion; import net.minecraft.util.Mth; -public class TransformedPart extends ColoredLitPart implements Transform { +public class TransformedInstance extends ColoredLitInstance implements Transform { private static final Matrix4f EMPTY_MATRIX_4f = new Matrix4f(); private static final Matrix3f EMPTY_MATRIX_3f = new Matrix3f(); public final Matrix4f model = new Matrix4f(); public final Matrix3f normal = new Matrix3f(); - public TransformedPart(StructType type, Handle handle) { + public TransformedInstance(InstanceType type, InstanceHandle handle) { super(type, handle); } - public TransformedPart setTransform(PoseStack stack) { + public TransformedInstance setTransform(PoseStack stack) { setChanged(); this.model.load(stack.last() @@ -38,7 +38,7 @@ public class TransformedPart extends ColoredLitPart implements Transform */ - public TransformedPart setEmptyTransform() { + public TransformedInstance setEmptyTransform() { setChanged(); this.model.load(EMPTY_MATRIX_4f); @@ -46,7 +46,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") + .addItem(CommonItems.MAT4, "pose") + .addItem(CommonItems.MAT3, "normal") + .build(); + + @Override + public TransformedInstance create(InstanceHandle handle) { + return new TransformedInstance(this, handle); + } + + @Override + public BufferLayout getLayout() { + return FORMAT; + } + + @Override + public InstanceWriter getWriter() { + return TransformedWriter.INSTANCE; + } + + @Override + public ResourceLocation instanceShader() { + return InstanceTypes.Files.TRANSFORMED; + } + + @Override + public InstanceVertexTransformer getVertexTransformer() { + return (vertexList, instance, level) -> { + float r = RenderMath.uf(instance.r); + float g = RenderMath.uf(instance.g); + float b = RenderMath.uf(instance.b); + float a = RenderMath.uf(instance.a); + int light = instance.getPackedLight(); + + for (int i = 0; i < vertexList.vertexCount(); i++) { + VertexTransformations.transformPos(vertexList, i, instance.model); + VertexTransformations.transformNormal(vertexList, i, instance.normal); + + vertexList.r(i, r); + vertexList.g(i, g); + vertexList.b(i, b); + vertexList.a(i, a); + vertexList.light(i, light); + } + }; + } +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedWriter.java b/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedWriter.java new file mode 100644 index 000000000..e9a1a544e --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/TransformedWriter.java @@ -0,0 +1,15 @@ +package com.jozufozu.flywheel.lib.instance; + +import com.jozufozu.flywheel.lib.math.MatrixUtil; + +public class TransformedWriter extends ColoredLitWriter { + public static final TransformedWriter INSTANCE = new TransformedWriter(); + + @Override + public void write(final long ptr, final TransformedInstance instance) { + super.write(ptr, instance); + MatrixUtil.writeUnsafe(instance.model, ptr + 8); + MatrixUtil.writeUnsafe(instance.normal, ptr + 72); + } + +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/math/MatrixUtil.java b/src/main/java/com/jozufozu/flywheel/lib/math/MatrixUtil.java index 8a1a25321..7ca9695a5 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/math/MatrixUtil.java +++ b/src/main/java/com/jozufozu/flywheel/lib/math/MatrixUtil.java @@ -93,6 +93,19 @@ public final class MatrixUtil { buf.putFloat(m.flywheel$m22()); } + public static void writeUnsafe(Matrix3f matrix, long ptr) { + Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix; + MemoryUtil.memPutFloat(ptr, m.flywheel$m00()); + MemoryUtil.memPutFloat(ptr + 4, m.flywheel$m10()); + MemoryUtil.memPutFloat(ptr + 8, m.flywheel$m20()); + MemoryUtil.memPutFloat(ptr + 12, m.flywheel$m01()); + MemoryUtil.memPutFloat(ptr + 16, m.flywheel$m11()); + MemoryUtil.memPutFloat(ptr + 20, m.flywheel$m21()); + MemoryUtil.memPutFloat(ptr + 24, m.flywheel$m02()); + MemoryUtil.memPutFloat(ptr + 28, m.flywheel$m12()); + MemoryUtil.memPutFloat(ptr + 32, m.flywheel$m22()); + } + public static void store(Matrix4f matrix, org.joml.Matrix4f jomlMatrix) { Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix; jomlMatrix.set( @@ -113,19 +126,6 @@ public final class MatrixUtil { ); } - public static void writeUnsafe(Matrix3f matrix, long ptr) { - Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix; - MemoryUtil.memPutFloat(ptr, m.flywheel$m00()); - MemoryUtil.memPutFloat(ptr + 4, m.flywheel$m10()); - MemoryUtil.memPutFloat(ptr + 8, m.flywheel$m20()); - MemoryUtil.memPutFloat(ptr + 12, m.flywheel$m01()); - MemoryUtil.memPutFloat(ptr + 16, m.flywheel$m11()); - MemoryUtil.memPutFloat(ptr + 20, m.flywheel$m21()); - MemoryUtil.memPutFloat(ptr + 24, m.flywheel$m02()); - MemoryUtil.memPutFloat(ptr + 28, m.flywheel$m12()); - MemoryUtil.memPutFloat(ptr + 32, m.flywheel$m22()); - } - public static void store(Matrix3f matrix, org.joml.Matrix3f jomlMatrix) { Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix; jomlMatrix.set( diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/PartialModel.java b/src/main/java/com/jozufozu/flywheel/lib/model/PartialModel.java index da858198d..3fa168cef 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/model/PartialModel.java +++ b/src/main/java/com/jozufozu/flywheel/lib/model/PartialModel.java @@ -16,7 +16,7 @@ import net.minecraftforge.client.model.ForgeModelBakery; * A helper class for loading and accessing json models. *
* Creating a PartialModel will make the associated modelLocation automatically load. - * PartialModels must be initialized the mod class constructor. + * PartialModels must be initialized in the mod class constructor. *
* Once {@link ModelBakeEvent} finishes, all PartialModels (with valid modelLocations) * will have their bakedModel fields populated. diff --git a/src/main/java/com/jozufozu/flywheel/lib/model/SimpleLazyModel.java b/src/main/java/com/jozufozu/flywheel/lib/model/SimpleLazyModel.java index 36b66ef9d..86424149b 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/model/SimpleLazyModel.java +++ b/src/main/java/com/jozufozu/flywheel/lib/model/SimpleLazyModel.java @@ -2,8 +2,6 @@ package com.jozufozu.flywheel.lib.model; import java.util.Map; -import org.jetbrains.annotations.NotNull; - import com.google.common.collect.ImmutableMap; import com.jozufozu.flywheel.api.material.Material; import com.jozufozu.flywheel.api.model.Mesh; @@ -13,18 +11,13 @@ import com.jozufozu.flywheel.util.NonNullSupplier; public class SimpleLazyModel implements Model { private final Lazy supplier; - private Material material; + private final Material material; public SimpleLazyModel(NonNullSupplier supplier, Material material) { this.supplier = Lazy.of(supplier); this.material = material; } - public SimpleLazyModel setMaterial(@NotNull Material material) { - this.material = material; - return this; - } - @Override public Map getMeshes() { return ImmutableMap.of(material, supplier.get()); 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 cfc6640fb..38642adf3 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,6 @@ 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.lib.format.Formats; import com.jozufozu.flywheel.lib.memory.MemoryBlock; import com.jozufozu.flywheel.lib.model.ModelUtil; import com.jozufozu.flywheel.lib.model.SimpleMesh; @@ -14,6 +13,7 @@ import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.BufferFactor import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ResultConsumer; import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ShadeSeparatedBufferFactory; import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ShadeSeparatedResultConsumer; +import com.jozufozu.flywheel.lib.vertex.VertexTypes; import com.jozufozu.flywheel.lib.virtualworld.VirtualEmptyBlockGetter; import com.jozufozu.flywheel.lib.virtualworld.VirtualEmptyModelData; import com.mojang.blaze3d.vertex.BufferBuilder; @@ -105,8 +105,8 @@ public class BakedModelBuilder { buffer.end(); Material material = materialFunc.apply(renderType, shaded); if (material != null) { - MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK); - meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded)); + MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), VertexTypes.BLOCK); + meshMapBuilder.put(material, new SimpleMesh(VertexTypes.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); @@ -120,8 +120,8 @@ public class BakedModelBuilder { buffer.end(); Material material = materialFunc.apply(renderType, false); if (material != null) { - MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK); - meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "bakedModel=" + bakedModel.toString() + ",renderType=" + renderType.toString())); + MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), VertexTypes.BLOCK); + meshMapBuilder.put(material, new SimpleMesh(VertexTypes.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 e5372f7d3..0008d73eb 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,6 @@ 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.lib.format.Formats; import com.jozufozu.flywheel.lib.memory.MemoryBlock; import com.jozufozu.flywheel.lib.model.ModelUtil; import com.jozufozu.flywheel.lib.model.SimpleMesh; @@ -14,6 +13,7 @@ import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.BufferFactor import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ResultConsumer; import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ShadeSeparatedBufferFactory; import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ShadeSeparatedResultConsumer; +import com.jozufozu.flywheel.lib.vertex.VertexTypes; import com.jozufozu.flywheel.lib.virtualworld.VirtualEmptyBlockGetter; import com.jozufozu.flywheel.lib.virtualworld.VirtualEmptyModelData; import com.mojang.blaze3d.vertex.BufferBuilder; @@ -94,8 +94,8 @@ public class BlockModelBuilder { buffer.end(); Material material = materialFunc.apply(renderType, shaded); if (material != null) { - MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK); - meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "state=" + state.toString() + ",renderType=" + renderType.toString() + ",shaded=" + shaded)); + MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), VertexTypes.BLOCK); + meshMapBuilder.put(material, new SimpleMesh(VertexTypes.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); @@ -109,8 +109,8 @@ public class BlockModelBuilder { buffer.end(); Material material = materialFunc.apply(renderType, false); if (material != null) { - MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK); - meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "state=" + state.toString() + ",renderType=" + renderType.toString())); + MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), VertexTypes.BLOCK); + meshMapBuilder.put(material, new SimpleMesh(VertexTypes.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 888e07405..ec4a4d36e 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,6 @@ 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.lib.format.Formats; import com.jozufozu.flywheel.lib.memory.MemoryBlock; import com.jozufozu.flywheel.lib.model.ModelUtil; import com.jozufozu.flywheel.lib.model.SimpleMesh; @@ -17,6 +16,7 @@ import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.BufferFactor import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ResultConsumer; import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ShadeSeparatedBufferFactory; import com.jozufozu.flywheel.lib.model.buffering.ModelBufferingUtil.ShadeSeparatedResultConsumer; +import com.jozufozu.flywheel.lib.vertex.VertexTypes; import com.jozufozu.flywheel.lib.virtualworld.VirtualEmptyBlockGetter; import com.mojang.blaze3d.vertex.BufferBuilder; import com.mojang.blaze3d.vertex.DefaultVertexFormat; @@ -101,8 +101,8 @@ public class MultiBlockModelBuilder { buffer.end(); Material material = materialFunc.apply(renderType, shaded); if (material != null) { - MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK); - meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "renderType=" + renderType.toString() + ",shaded=" + shaded)); + MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), VertexTypes.BLOCK); + meshMapBuilder.put(material, new SimpleMesh(VertexTypes.BLOCK, data, "renderType=" + renderType.toString() + ",shaded=" + shaded)); } }; ModelBufferingUtil.bufferMultiBlockShadeSeparated(blocks, ModelUtil.VANILLA_RENDERER, renderWorld, poseStack, bufferFactory, objects.shadeSeparatingBufferWrapper, objects.random, modelDataMap, resultConsumer); @@ -116,8 +116,8 @@ public class MultiBlockModelBuilder { buffer.end(); Material material = materialFunc.apply(renderType, false); if (material != null) { - MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), Formats.BLOCK); - meshMapBuilder.put(material, new SimpleMesh(Formats.BLOCK, data, "renderType=" + renderType.toString())); + MemoryBlock data = ModelUtil.convertVanillaBuffer(buffer.popNextBuffer(), VertexTypes.BLOCK); + meshMapBuilder.put(material, new SimpleMesh(VertexTypes.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 7a56cef2d..e6b1f544c 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPart.java +++ b/src/main/java/com/jozufozu/flywheel/lib/modelpart/ModelPart.java @@ -7,11 +7,11 @@ import org.joml.Vector4fc; 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; +import com.jozufozu.flywheel.lib.vertex.PosTexNormalVertex; +import com.jozufozu.flywheel.lib.vertex.VertexTypes; public class ModelPart implements QuadMesh { private final int vertexCount; @@ -45,7 +45,7 @@ public class ModelPart implements QuadMesh { @Override public PosTexNormalVertex getVertexType() { - return Formats.POS_TEX_NORMAL; + return VertexTypes.POS_TEX_NORMAL; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/lib/pipeline/SimplePipeline.java b/src/main/java/com/jozufozu/flywheel/lib/pipeline/SimplePipeline.java index 9e384b7bf..33fc8da4d 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/pipeline/SimplePipeline.java +++ b/src/main/java/com/jozufozu/flywheel/lib/pipeline/SimplePipeline.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.lib.pipeline; +import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.pipeline.Pipeline; -import com.jozufozu.flywheel.api.struct.StructType; import com.jozufozu.flywheel.gl.GLSLVersion; import com.jozufozu.flywheel.glsl.SourceComponent; @@ -21,9 +21,9 @@ public final class SimplePipeline implements Pipeline { } /** - * Generate the source component necessary to convert a packed {@link StructType} into its shader representation. + * Generate the source component necessary to convert a packed {@link InstanceType} into its shader representation. * - * @return A source component defining functions that unpack a representation of the given struct type. + * @return A source component defining functions that unpack a representation of the given instance type. */ @Override public SourceComponent assemble(InstanceAssemblerContext context) { diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/AbstractInstancePart.java b/src/main/java/com/jozufozu/flywheel/lib/struct/AbstractInstancePart.java deleted file mode 100644 index fde6ab5b5..000000000 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/AbstractInstancePart.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.jozufozu.flywheel.lib.struct; - -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 { - protected final StructType type; - protected final Handle handle; - - protected AbstractInstancePart(StructType type, Handle handle) { - this.type = type; - this.handle = handle; - } - - @Override - public StructType type() { - return type; - } - - public final void setChanged() { - handle.setChanged(); - } - - public final void delete() { - handle.setDeleted(); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitWriter.java b/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitWriter.java deleted file mode 100644 index d1a9fef2d..000000000 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/ColoredLitWriter.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.jozufozu.flywheel.lib.struct; - -import org.lwjgl.system.MemoryUtil; - -import com.jozufozu.flywheel.api.struct.StructWriter; - -public abstract class ColoredLitWriter implements StructWriter { - @Override - public void write(final long ptr, final D d) { - MemoryUtil.memPutShort(ptr, d.blockLight); - MemoryUtil.memPutShort(ptr + 2, d.skyLight); - MemoryUtil.memPutByte(ptr + 4, d.r); - MemoryUtil.memPutByte(ptr + 5, d.g); - MemoryUtil.memPutByte(ptr + 6, d.b); - MemoryUtil.memPutByte(ptr + 7, d.a); - } -} diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedWriter.java b/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedWriter.java deleted file mode 100644 index a16ea7a0e..000000000 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/OrientedWriter.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.jozufozu.flywheel.lib.struct; - -import org.lwjgl.system.MemoryUtil; - -public class OrientedWriter extends ColoredLitWriter { - public static final OrientedWriter INSTANCE = new OrientedWriter(); - - @Override - public void write(long ptr, OrientedPart d) { - super.write(ptr, d); - - MemoryUtil.memPutFloat(ptr + 8, d.posX); - MemoryUtil.memPutFloat(ptr + 12, d.posY); - MemoryUtil.memPutFloat(ptr + 16, d.posZ); - MemoryUtil.memPutFloat(ptr + 20, d.pivotX); - MemoryUtil.memPutFloat(ptr + 24, d.pivotY); - MemoryUtil.memPutFloat(ptr + 28, d.pivotZ); - MemoryUtil.memPutFloat(ptr + 32, d.qX); - MemoryUtil.memPutFloat(ptr + 36, d.qY); - MemoryUtil.memPutFloat(ptr + 40, d.qZ); - MemoryUtil.memPutFloat(ptr + 44, d.qW); - } - -} diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedType.java b/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedType.java deleted file mode 100644 index d1b5aa521..000000000 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedType.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.jozufozu.flywheel.lib.struct; - -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.lib.math.RenderMath; -import com.jozufozu.flywheel.lib.vertex.VertexTransformations; - -import net.minecraft.resources.ResourceLocation; - -public class TransformedType implements StructType { - public static final BufferLayout FORMAT = BufferLayout.builder() - .addItem(CommonItems.LIGHT_COORD, "light") - .addItem(CommonItems.UNORM_4x8, "color") - .addItem(CommonItems.MAT4, "pose") - .addItem(CommonItems.MAT3, "normal") - .build(); - - @Override - public TransformedPart create(Handle handle) { - return new TransformedPart(this, handle); - } - - @Override - public BufferLayout getLayout() { - return FORMAT; - } - - @Override - public StructWriter getWriter() { - return TransformedWriter.INSTANCE; - } - - @Override - public ResourceLocation instanceShader() { - return StructTypes.Files.TRANSFORMED; - } - - @Override - public StructVertexTransformer getVertexTransformer() { - return (vertexList, struct, level) -> { - float r = RenderMath.uf(struct.r); - float g = RenderMath.uf(struct.g); - float b = RenderMath.uf(struct.b); - float a = RenderMath.uf(struct.a); - int light = struct.getPackedLight(); - - for (int i = 0; i < vertexList.vertexCount(); i++) { - VertexTransformations.transformPos(vertexList, i, struct.model); - VertexTransformations.transformNormal(vertexList, i, struct.normal); - - vertexList.r(i, r); - vertexList.g(i, g); - vertexList.b(i, b); - vertexList.a(i, a); - vertexList.light(i, light); - } - }; - } -} diff --git a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedWriter.java b/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedWriter.java deleted file mode 100644 index e18d14f9c..000000000 --- a/src/main/java/com/jozufozu/flywheel/lib/struct/TransformedWriter.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.jozufozu.flywheel.lib.struct; - -import com.jozufozu.flywheel.lib.math.MatrixUtil; - -public class TransformedWriter extends ColoredLitWriter { - public static final TransformedWriter INSTANCE = new TransformedWriter(); - - @Override - public void write(final long ptr, final TransformedPart d) { - super.write(ptr, d); - MatrixUtil.writeUnsafe(d.model, ptr + 8); - MatrixUtil.writeUnsafe(d.normal, ptr + 72); - } - -} 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 4f88499ac..b33e94a0b 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/uniform/FlwShaderUniforms.java +++ b/src/main/java/com/jozufozu/flywheel/lib/uniform/FlwShaderUniforms.java @@ -8,7 +8,7 @@ import com.jozufozu.flywheel.Flywheel; 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.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.lib.math.MatrixUtil; import com.jozufozu.flywheel.lib.math.MoreMath; import com.mojang.blaze3d.systems.RenderSystem; @@ -73,7 +73,7 @@ public class FlwShaderUniforms implements ShaderUniforms { } RenderContext context = event.getContext(); - Vec3i renderOrigin = InstancedRenderDispatcher.getRenderOrigin(context.level()); + Vec3i renderOrigin = VisualizedRenderDispatcher.getRenderOrigin(context.level()); Vec3 camera = context.camera() .getPosition(); diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/AbstractVertexList.java b/src/main/java/com/jozufozu/flywheel/lib/vertex/AbstractVertexList.java similarity index 91% rename from src/main/java/com/jozufozu/flywheel/lib/format/AbstractVertexList.java rename to src/main/java/com/jozufozu/flywheel/lib/vertex/AbstractVertexList.java index 387ca3cfb..99e9d7fd3 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/format/AbstractVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/lib/vertex/AbstractVertexList.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.lib.format; +package com.jozufozu.flywheel.lib.vertex; import com.jozufozu.flywheel.api.vertex.ReusableVertexList; diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/BlockVertex.java b/src/main/java/com/jozufozu/flywheel/lib/vertex/BlockVertex.java similarity index 90% rename from src/main/java/com/jozufozu/flywheel/lib/format/BlockVertex.java rename to src/main/java/com/jozufozu/flywheel/lib/vertex/BlockVertex.java index 1294ea839..8728b8b40 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/format/BlockVertex.java +++ b/src/main/java/com/jozufozu/flywheel/lib/vertex/BlockVertex.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.lib.format; +package com.jozufozu.flywheel.lib.vertex; import com.jozufozu.flywheel.api.layout.BufferLayout; import com.jozufozu.flywheel.api.vertex.VertexType; @@ -23,7 +23,7 @@ public class BlockVertex implements VertexType { @Override public ResourceLocation layoutShader() { - return Formats.Files.BLOCK_LAYOUT; + return VertexTypes.Files.BLOCK_LAYOUT; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/BlockVertexList.java b/src/main/java/com/jozufozu/flywheel/lib/vertex/BlockVertexList.java similarity index 99% rename from src/main/java/com/jozufozu/flywheel/lib/format/BlockVertexList.java rename to src/main/java/com/jozufozu/flywheel/lib/vertex/BlockVertexList.java index 45b56f035..af6039f9e 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/format/BlockVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/lib/vertex/BlockVertexList.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.lib.format; +package com.jozufozu.flywheel.lib.vertex; import org.lwjgl.system.MemoryUtil; diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertex.java b/src/main/java/com/jozufozu/flywheel/lib/vertex/PosTexNormalVertex.java similarity index 88% rename from src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertex.java rename to src/main/java/com/jozufozu/flywheel/lib/vertex/PosTexNormalVertex.java index 92f74b5ec..97dc56745 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertex.java +++ b/src/main/java/com/jozufozu/flywheel/lib/vertex/PosTexNormalVertex.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.lib.format; +package com.jozufozu.flywheel.lib.vertex; import com.jozufozu.flywheel.api.layout.BufferLayout; import com.jozufozu.flywheel.api.vertex.VertexType; @@ -20,7 +20,7 @@ public class PosTexNormalVertex implements VertexType { @Override public ResourceLocation layoutShader() { - return Formats.Files.POS_TEX_NORMAL_LAYOUT; + return VertexTypes.Files.POS_TEX_NORMAL_LAYOUT; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertexList.java b/src/main/java/com/jozufozu/flywheel/lib/vertex/PosTexNormalVertexList.java similarity index 98% rename from src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertexList.java rename to src/main/java/com/jozufozu/flywheel/lib/vertex/PosTexNormalVertexList.java index 5581d5844..727b52bde 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/format/PosTexNormalVertexList.java +++ b/src/main/java/com/jozufozu/flywheel/lib/vertex/PosTexNormalVertexList.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.lib.format; +package com.jozufozu.flywheel.lib.vertex; import org.lwjgl.system.MemoryUtil; diff --git a/src/main/java/com/jozufozu/flywheel/lib/format/Formats.java b/src/main/java/com/jozufozu/flywheel/lib/vertex/VertexTypes.java similarity index 92% rename from src/main/java/com/jozufozu/flywheel/lib/format/Formats.java rename to src/main/java/com/jozufozu/flywheel/lib/vertex/VertexTypes.java index 7955bbb15..071d209da 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/format/Formats.java +++ b/src/main/java/com/jozufozu/flywheel/lib/vertex/VertexTypes.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.lib.format; +package com.jozufozu.flywheel.lib.vertex; import org.jetbrains.annotations.ApiStatus; @@ -8,7 +8,7 @@ import com.jozufozu.flywheel.util.ResourceUtil; import net.minecraft.resources.ResourceLocation; -public final class Formats { +public final class VertexTypes { public static final BlockVertex BLOCK = VertexType.REGISTRY.registerAndGet(new BlockVertex()); public static final PosTexNormalVertex POS_TEX_NORMAL = VertexType.REGISTRY.registerAndGet(new PosTexNormalVertex()); diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractBlockEntityVisual.java similarity index 53% rename from src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java rename to src/main/java/com/jozufozu/flywheel/lib/visual/AbstractBlockEntityVisual.java index 73491dbcd..e3f35ecca 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractBlockEntityVisual.java @@ -1,12 +1,12 @@ -package com.jozufozu.flywheel.lib.instance; +package com.jozufozu.flywheel.lib.visual; import org.joml.FrustumIntersection; -import com.jozufozu.flywheel.api.instance.BlockEntityInstance; -import com.jozufozu.flywheel.api.instance.DynamicInstance; -import com.jozufozu.flywheel.api.instance.TickableInstance; -import com.jozufozu.flywheel.api.instance.controller.InstanceContext; -import com.jozufozu.flywheel.impl.instancing.manager.BlockEntityInstanceManager; +import com.jozufozu.flywheel.api.visual.BlockEntityVisual; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visual.TickableVisual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityVisualManager; import com.jozufozu.flywheel.lib.box.ImmutableBox; import com.jozufozu.flywheel.lib.box.MutableBox; @@ -17,42 +17,34 @@ import net.minecraft.world.level.block.state.BlockState; /** * The layer between a {@link BlockEntity} and the Flywheel backend. * - *

{@link #updateLight()} is called after construction. + *

{@link #updateLight()} is called after initialization. * *

There are a few additional features that overriding classes can opt in to: *

    - *
  • {@link DynamicInstance}
  • - *
  • {@link TickableInstance}
  • + *
  • {@link DynamicVisual}
  • + *
  • {@link TickableVisual}
  • *
* See the interfaces' documentation for more information about each one. * - *
Implementing one or more of these will give an {@link AbstractBlockEntityInstance} access + *
Implementing one or more of these will give an {@link AbstractBlockEntityVisual} access * to more interesting and regular points within a tick or a frame. * - * @param The type of {@link BlockEntity} your class is an instance of. + * @param The type of {@link BlockEntity}. */ -public abstract class AbstractBlockEntityInstance extends AbstractInstance implements BlockEntityInstance { +public abstract class AbstractBlockEntityVisual extends AbstractVisual implements BlockEntityVisual { protected final T blockEntity; protected final BlockPos pos; - protected final BlockPos instancePos; + protected final BlockPos visualPos; protected final BlockState blockState; - public AbstractBlockEntityInstance(InstanceContext ctx, T blockEntity) { + public AbstractBlockEntityVisual(VisualizationContext ctx, T blockEntity) { super(ctx, blockEntity.getLevel()); this.blockEntity = blockEntity; this.pos = blockEntity.getBlockPos(); this.blockState = blockEntity.getBlockState(); - this.instancePos = pos.subtract(renderOrigin); + this.visualPos = pos.subtract(renderOrigin); } - /** - * Just before {@link #update()} would be called, {@code shouldReset()} is checked. - * If this function returns {@code true}, then this instance will be {@link #delete removed}, - * and another instance will be constructed to replace it. This allows for more sane resource - * acquisition compared to trying to update everything within the lifetime of an instance. - * - * @return {@code true} if this instance should be discarded and refreshed. - */ @Override public boolean shouldReset() { return blockEntity.getBlockState() != blockState; @@ -70,13 +62,13 @@ public abstract class AbstractBlockEntityInstance extends /** * In order to accommodate for floating point precision errors at high coordinates, - * {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and + * {@link BlockEntityVisualManager}s are allowed to arbitrarily adjust the origin, and * shift the world matrix provided as a shader uniform accordingly. * - * @return The {@link BlockPos position} of the {@link BlockEntity} this instance + * @return The {@link BlockPos position} of the {@link BlockEntity} this visual * represents should be rendered at to appear in the correct location. */ - public BlockPos getInstancePosition() { + public BlockPos getVisualPosition() { return pos.subtract(renderOrigin); } diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractEntityVisual.java similarity index 65% rename from src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java rename to src/main/java/com/jozufozu/flywheel/lib/visual/AbstractEntityVisual.java index f2ab16121..4d79c7656 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractEntityVisual.java @@ -1,12 +1,12 @@ -package com.jozufozu.flywheel.lib.instance; +package com.jozufozu.flywheel.lib.visual; import org.joml.FrustumIntersection; -import com.jozufozu.flywheel.api.instance.DynamicInstance; -import com.jozufozu.flywheel.api.instance.EntityInstance; -import com.jozufozu.flywheel.api.instance.TickableInstance; -import com.jozufozu.flywheel.api.instance.controller.InstanceContext; -import com.jozufozu.flywheel.impl.instancing.manager.BlockEntityInstanceManager; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visual.EntityVisual; +import com.jozufozu.flywheel.api.visual.TickableVisual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityVisualManager; import com.jozufozu.flywheel.lib.box.ImmutableBox; import com.jozufozu.flywheel.lib.box.MutableBox; import com.jozufozu.flywheel.lib.light.TickingLightListener; @@ -22,21 +22,21 @@ import net.minecraft.world.phys.Vec3; * * *

There are a few additional features that overriding classes can opt in to: *
    - *
  • {@link DynamicInstance}
  • - *
  • {@link TickableInstance}
  • + *
  • {@link DynamicVisual}
  • + *
  • {@link TickableVisual}
  • *
* See the interfaces' documentation for more information about each one. * - *
Implementing one or more of these will give an {@link AbstractEntityInstance} access + *
Implementing one or more of these will give an {@link AbstractEntityVisual} access * to more interesting and regular points within a tick or a frame. * - * @param The type of {@link Entity} your class is an instance of. + * @param The type of {@link Entity}. */ -public abstract class AbstractEntityInstance extends AbstractInstance implements EntityInstance, TickingLightListener { - protected final E entity; +public abstract class AbstractEntityVisual extends AbstractVisual implements EntityVisual, TickingLightListener { + protected final T entity; protected final MutableBox bounds; - public AbstractEntityInstance(InstanceContext ctx, E entity) { + public AbstractEntityVisual(VisualizationContext ctx, T entity) { super(ctx, entity.level); this.entity = entity; bounds = MutableBox.from(entity.getBoundingBox()); @@ -69,24 +69,24 @@ public abstract class AbstractEntityInstance extends AbstractI /** * In order to accommodate for floating point precision errors at high coordinates, - * {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and + * {@link BlockEntityVisualManager}s are allowed to arbitrarily adjust the origin, and * shift the world matrix provided as a shader uniform accordingly. * - * @return The position this instance should be rendered at to appear in the correct location. + * @return The position this visual should be rendered at to appear in the correct location. */ - public Vector3f getInstancePosition() { + public Vector3f getVisualPosition() { Vec3 pos = entity.position(); return new Vector3f((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ())); } /** * In order to accommodate for floating point precision errors at high coordinates, - * {@link BlockEntityInstanceManager}s are allowed to arbitrarily adjust the origin, and + * {@link BlockEntityVisualManager}s are allowed to arbitrarily adjust the origin, and * shift the world matrix provided as a shader uniform accordingly. * - * @return The position this instance should be rendered at to appear in the correct location. + * @return The position this visual should be rendered at to appear in the correct location. */ - public Vector3f getInstancePosition(float partialTicks) { + public Vector3f getVisualPosition(float partialTicks) { Vec3 pos = entity.position(); return new Vector3f((float) (Mth.lerp(partialTicks, entity.xOld, pos.x) - renderOrigin.getX()), (float) (Mth.lerp(partialTicks, entity.yOld, pos.y) - renderOrigin.getY()), (float) (Mth.lerp(partialTicks, entity.zOld, pos.z) - renderOrigin.getZ())); } diff --git a/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractVisual.java b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractVisual.java new file mode 100644 index 000000000..bd1753657 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractVisual.java @@ -0,0 +1,93 @@ +package com.jozufozu.flywheel.lib.visual; + +import java.util.stream.Stream; + +import com.jozufozu.flywheel.api.instance.InstancerProvider; +import com.jozufozu.flywheel.api.visual.Visual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.lib.instance.FlatLit; +import com.jozufozu.flywheel.lib.light.LightListener; +import com.jozufozu.flywheel.lib.light.LightUpdater; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.SectionPos; +import net.minecraft.core.Vec3i; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LightLayer; + +public abstract class AbstractVisual implements Visual, LightListener { + protected final InstancerProvider instancerProvider; + protected final Vec3i renderOrigin; + protected final Level level; + + protected boolean deleted = false; + + public AbstractVisual(VisualizationContext ctx, Level level) { + this.instancerProvider = ctx.instancerProvider(); + this.renderOrigin = ctx.renderOrigin(); + this.level = level; + } + + @Override + public void init() { + LightUpdater.get(level).addListener(this); + updateLight(); + } + + @Override + public void update() { + } + + @Override + public boolean shouldReset() { + return false; + } + + /** + * Called after initialization and when a light update occurs in the world. + * + *
If your instances need it, update light here. + */ + public void updateLight() { + } + + protected abstract void _delete(); + + @Override + public final void delete() { + if (deleted) { + return; + } + + _delete(); + deleted = true; + } + + @Override + public void onLightUpdate(LightLayer type, SectionPos pos) { + updateLight(); + } + + @Override + public boolean isInvalid() { + return deleted; + } + + protected void relight(BlockPos pos, FlatLit... instances) { + relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), instances); + } + + protected void relight(int block, int sky, FlatLit... instances) { + for (FlatLit instance : instances) { + instance.setLight(block, sky); + } + } + + protected > void relight(BlockPos pos, Stream instances) { + relight(level.getBrightness(LightLayer.BLOCK, pos), level.getBrightness(LightLayer.SKY, pos), instances); + } + + protected > void relight(int block, int sky, Stream instances) { + instances.forEach(model -> model.setLight(block, sky)); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/visual/SimpleBlockEntityVisualizer.java b/src/main/java/com/jozufozu/flywheel/lib/visual/SimpleBlockEntityVisualizer.java new file mode 100644 index 000000000..24e01cfdf --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/visual/SimpleBlockEntityVisualizer.java @@ -0,0 +1,109 @@ +package com.jozufozu.flywheel.lib.visual; + +import java.util.Objects; +import java.util.function.Predicate; + +import org.jetbrains.annotations.NotNull; + +import com.jozufozu.flywheel.api.visual.BlockEntityVisual; +import com.jozufozu.flywheel.api.visualization.BlockEntityVisualizer; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.api.visualization.VisualizerRegistry; + +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.entity.BlockEntityType; + +public class SimpleBlockEntityVisualizer implements BlockEntityVisualizer { + protected Factory visualFactory; + protected Predicate skipRender; + + public SimpleBlockEntityVisualizer(Factory visualFactory, Predicate skipRender) { + this.visualFactory = visualFactory; + this.skipRender = skipRender; + } + + @Override + public BlockEntityVisual createVisual(VisualizationContext ctx, T blockEntity) { + return visualFactory.create(ctx, blockEntity); + } + + @Override + public boolean shouldSkipRender(T blockEntity) { + return skipRender.test(blockEntity); + } + + /** + * Get an object to configure the visualizer for the given block entity type. + * + * @param type The block entity type to configure. + * @param The type of the block entity. + * @return The configuration object. + */ + public static BlockEntityConfig configure(BlockEntityType type) { + return new BlockEntityConfig<>(type); + } + + @FunctionalInterface + public interface Factory { + @NotNull BlockEntityVisual create(VisualizationContext ctx, T blockEntity); + } + + /** + * An object to configure the visualizer for a block entity. + * + * @param The type of the block entity. + */ + public static class BlockEntityConfig { + protected BlockEntityType type; + protected Factory visualFactory; + protected Predicate skipRender; + + public BlockEntityConfig(BlockEntityType type) { + this.type = type; + } + + /** + * Sets the visual factory for the block entity. + * + * @param visualFactory The visual factory. + * @return {@code this} + */ + public BlockEntityConfig factory(Factory visualFactory) { + this.visualFactory = visualFactory; + return this; + } + + /** + * Sets a predicate to determine whether to skip rendering a block entity. + * @param skipRender The predicate. + * @return {@code this} + */ + public BlockEntityConfig skipRender(Predicate skipRender) { + this.skipRender = skipRender; + return this; + } + + /** + * Sets a predicate to always skip rendering for block entities of this type. + * @return {@code this} + */ + public BlockEntityConfig alwaysSkipRender() { + this.skipRender = be -> true; + return this; + } + + /** + * Constructs the block entity visualizer, and sets it for the block entity type. + * @return The block entity visualizer. + */ + public SimpleBlockEntityVisualizer apply() { + Objects.requireNonNull(visualFactory, "Visual factory cannot be null!"); + if (skipRender == null) { + skipRender = be -> false; + } + SimpleBlockEntityVisualizer visualizer = new SimpleBlockEntityVisualizer<>(visualFactory, skipRender); + VisualizerRegistry.setVisualizer(type, visualizer); + return visualizer; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/lib/visual/SimpleEntityVisualizer.java b/src/main/java/com/jozufozu/flywheel/lib/visual/SimpleEntityVisualizer.java new file mode 100644 index 000000000..483f307ef --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/lib/visual/SimpleEntityVisualizer.java @@ -0,0 +1,109 @@ +package com.jozufozu.flywheel.lib.visual; + +import java.util.Objects; +import java.util.function.Predicate; + +import org.jetbrains.annotations.NotNull; + +import com.jozufozu.flywheel.api.visual.EntityVisual; +import com.jozufozu.flywheel.api.visualization.EntityVisualizer; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.api.visualization.VisualizerRegistry; + +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; + +public class SimpleEntityVisualizer implements EntityVisualizer { + protected Factory visualFactory; + protected Predicate skipRender; + + public SimpleEntityVisualizer(Factory visualFactory, Predicate skipRender) { + this.visualFactory = visualFactory; + this.skipRender = skipRender; + } + + @Override + public EntityVisual createVisual(VisualizationContext ctx, T entity) { + return visualFactory.create(ctx, entity); + } + + @Override + public boolean shouldSkipRender(T entity) { + return skipRender.test(entity); + } + + /** + * Get an object to configure the visualizer for the given entity type. + * + * @param type The entity type to configure. + * @param The type of the entity. + * @return The configuration object. + */ + public static EntityConfig configure(EntityType type) { + return new EntityConfig<>(type); + } + + @FunctionalInterface + public interface Factory { + @NotNull EntityVisual create(VisualizationContext ctx, T entity); + } + + /** + * An object to configure the visualizer for an entity. + * + * @param The type of the entity. + */ + public static class EntityConfig { + protected EntityType type; + protected Factory visualFactory; + protected Predicate skipRender; + + public EntityConfig(EntityType type) { + this.type = type; + } + + /** + * Sets the visual factory for the entity. + * + * @param visualFactory The visual factory. + * @return {@code this} + */ + public EntityConfig factory(Factory visualFactory) { + this.visualFactory = visualFactory; + return this; + } + + /** + * Sets a predicate to determine whether to skip rendering an entity. + * @param skipRender The predicate. + * @return {@code this} + */ + public EntityConfig skipRender(Predicate skipRender) { + this.skipRender = skipRender; + return this; + } + + /** + * Sets a predicate to always skip rendering for entities of this type. + * @return {@code this} + */ + public EntityConfig alwaysSkipRender() { + this.skipRender = entity -> true; + return this; + } + + /** + * Constructs the entity visualizer, and sets it for the entity type. + * @return The entity visualizer. + */ + public SimpleEntityVisualizer apply() { + Objects.requireNonNull(visualFactory, "Visual factory cannot be null!"); + if (skipRender == null) { + skipRender = entity -> false; + } + SimpleEntityVisualizer visualizer = new SimpleEntityVisualizer<>(visualFactory, skipRender); + VisualizerRegistry.setVisualizer(type, visualizer); + return visualizer; + } + } +} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java index 6626815be..dcb277da3 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/BlockEntityTypeMixin.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import com.jozufozu.flywheel.api.instance.controller.BlockEntityInstancingController; +import com.jozufozu.flywheel.api.visualization.BlockEntityVisualizer; import com.jozufozu.flywheel.extension.BlockEntityTypeExtension; import net.minecraft.world.level.block.entity.BlockEntity; @@ -13,16 +13,16 @@ import net.minecraft.world.level.block.entity.BlockEntityType; @Mixin(BlockEntityType.class) public class BlockEntityTypeMixin implements BlockEntityTypeExtension { @Unique - private BlockEntityInstancingController flywheel$instancingController; + private BlockEntityVisualizer flywheel$visualizer; @Override @Nullable - public BlockEntityInstancingController flywheel$getInstancingController() { - return flywheel$instancingController; + public BlockEntityVisualizer flywheel$getVisualizer() { + return flywheel$visualizer; } @Override - public void flywheel$setInstancingController(@Nullable BlockEntityInstancingController instancingController) { - this.flywheel$instancingController = instancingController; + public void flywheel$setVisualizer(@Nullable BlockEntityVisualizer visualizer) { + this.flywheel$visualizer = visualizer; } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java index 5e459f9f1..e4d65813c 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/ClientLevelMixin.java @@ -10,7 +10,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.google.common.collect.Lists; import com.jozufozu.flywheel.extension.ClientLevelExtension; -import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper; +import com.jozufozu.flywheel.impl.visualization.VisualizationHelper; import com.jozufozu.flywheel.util.FlwUtil; import net.minecraft.client.multiplayer.ClientLevel; @@ -29,11 +29,11 @@ public abstract class ClientLevelMixin implements ClientLevelExtension { @Inject(method = "entitiesForRendering", at = @At("RETURN"), cancellable = true) private void flywheel$filterEntities(CallbackInfoReturnable> cir) { - if (FlwUtil.canUseInstancing((ClientLevel) (Object) this)) { + if (FlwUtil.canUseVisualization((ClientLevel) (Object) this)) { Iterable entities = cir.getReturnValue(); ArrayList filtered = Lists.newArrayList(entities); - filtered.removeIf(InstancingControllerHelper::shouldSkipRender); + filtered.removeIf(VisualizationHelper::shouldSkipRender); cir.setReturnValue(filtered); } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java index c20cabb6d..65cc060ec 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/EntityTypeMixin.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import com.jozufozu.flywheel.api.instance.controller.EntityInstancingController; +import com.jozufozu.flywheel.api.visualization.EntityVisualizer; import com.jozufozu.flywheel.extension.EntityTypeExtension; import net.minecraft.world.entity.Entity; @@ -13,16 +13,16 @@ import net.minecraft.world.entity.EntityType; @Mixin(EntityType.class) public class EntityTypeMixin implements EntityTypeExtension { @Unique - private EntityInstancingController flywheel$instancingController; + private EntityVisualizer flywheel$visualizer; @Override @Nullable - public EntityInstancingController flywheel$getInstancingController() { - return flywheel$instancingController; + public EntityVisualizer flywheel$getVisualizer() { + return flywheel$visualizer; } @Override - public void flywheel$setInstancingController(@Nullable EntityInstancingController instancingController) { - this.flywheel$instancingController = instancingController; + public void flywheel$setVisualizer(@Nullable EntityVisualizer visualizer) { + this.flywheel$visualizer = visualizer; } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java deleted file mode 100644 index 4a6df32db..000000000 --- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceRemoveMixin.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.jozufozu.flywheel.mixin.instancemanage; - -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -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; -import net.minecraft.world.level.block.entity.BlockEntity; - -@Mixin(BlockEntity.class) -public class InstanceRemoveMixin { - @Shadow - @Nullable - protected Level level; - - @Inject(at = @At("TAIL"), method = "setRemoved") - private void flywheel$removeInstance(CallbackInfo ci) { - if (level instanceof ClientLevel && FlwUtil.canUseInstancing(level)) { - InstancedRenderDispatcher.getBlockEntities(level) - .remove((BlockEntity) (Object) this); - } - } - -// /** -// * Don't do this. -// * It can cause infinite loops if an instance class tries to access another block entity in its constructor. -// */ -// @Inject(at = @At("TAIL"), method = "clearRemoved") -// private void addInstance(CallbackInfo ci) { -// if (level.isClientSide) InstancedRenderDispatcher.getBlockEntities(this.level) -// .add((BlockEntity) (Object) this); -// } -} diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/visualmanage/ChunkRebuildHooksMixin.java similarity index 65% rename from src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java rename to src/main/java/com/jozufozu/flywheel/mixin/visualmanage/ChunkRebuildHooksMixin.java index 324114960..fddc991cc 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/ChunkRebuildHooksMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/visualmanage/ChunkRebuildHooksMixin.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.mixin.instancemanage; +package com.jozufozu.flywheel.mixin.visualmanage; import java.util.Set; @@ -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.impl.instancing.InstancedRenderDispatcher; -import com.jozufozu.flywheel.impl.instancing.InstancingControllerHelper; +import com.jozufozu.flywheel.impl.visualization.VisualizationHelper; +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.util.FlwUtil; import net.minecraft.client.renderer.chunk.ChunkRenderDispatcher; @@ -18,11 +18,11 @@ 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 (FlwUtil.canUseInstancing(be.getLevel())) { - if (InstancingControllerHelper.canInstance(be)) - InstancedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be); + if (FlwUtil.canUseVisualization(be.getLevel())) { + if (VisualizationHelper.canVisualize(be)) + VisualizedRenderDispatcher.getBlockEntities(be.getLevel()).queueAdd(be); - if (InstancingControllerHelper.shouldSkipRender(be)) + if (VisualizationHelper.shouldSkipRender(be)) ci.cancel(); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/visualmanage/VisualAddMixin.java similarity index 75% rename from src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java rename to src/main/java/com/jozufozu/flywheel/mixin/visualmanage/VisualAddMixin.java index 601bb9b72..64cb29d9f 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceAddMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/visualmanage/VisualAddMixin.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.mixin.instancemanage; +package com.jozufozu.flywheel.mixin.visualmanage; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -7,7 +7,7 @@ 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.impl.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.util.FlwUtil; import net.minecraft.world.level.Level; @@ -15,7 +15,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.chunk.LevelChunk; @Mixin(LevelChunk.class) -public class InstanceAddMixin { +public class VisualAddMixin { @Shadow @Final Level level; @@ -23,8 +23,8 @@ 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 && FlwUtil.canUseInstancing(level)) { - InstancedRenderDispatcher.getBlockEntities(level) + if (level.isClientSide && FlwUtil.canUseVisualization(level)) { + VisualizedRenderDispatcher.getBlockEntities(level) .add(blockEntity); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/visualmanage/VisualRemoveMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/visualmanage/VisualRemoveMixin.java new file mode 100644 index 000000000..b97d33d26 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/visualmanage/VisualRemoveMixin.java @@ -0,0 +1,30 @@ +package com.jozufozu.flywheel.mixin.visualmanage; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; +import com.jozufozu.flywheel.util.FlwUtil; + +import net.minecraft.client.multiplayer.ClientLevel; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.entity.BlockEntity; + +@Mixin(BlockEntity.class) +public class VisualRemoveMixin { + @Shadow + @Nullable + protected Level level; + + @Inject(at = @At("TAIL"), method = "setRemoved") + private void flywheel$removeVisual(CallbackInfo ci) { + if (level instanceof ClientLevel && FlwUtil.canUseVisualization(level)) { + VisualizedRenderDispatcher.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/visualmanage/VisualUpdateMixin.java similarity index 81% rename from src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceUpdateMixin.java rename to src/main/java/com/jozufozu/flywheel/mixin/visualmanage/VisualUpdateMixin.java index 363e1dc0e..455656ef6 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/instancemanage/InstanceUpdateMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/visualmanage/VisualUpdateMixin.java @@ -1,4 +1,4 @@ -package com.jozufozu.flywheel.mixin.instancemanage; +package com.jozufozu.flywheel.mixin.visualmanage; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -6,7 +6,7 @@ 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.impl.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.util.FlwUtil; import net.minecraft.client.multiplayer.ClientLevel; @@ -16,7 +16,7 @@ import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; @Mixin(LevelRenderer.class) -public class InstanceUpdateMixin { +public class VisualUpdateMixin { @Shadow private ClientLevel level; @@ -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 (!FlwUtil.canUseInstancing(level)) { + if (!FlwUtil.canUseVisualization(level)) { return; } BlockEntity blockEntity = level.getBlockEntity(pos); @@ -34,7 +34,7 @@ public class InstanceUpdateMixin { return; } - InstancedRenderDispatcher.getBlockEntities(level) + VisualizedRenderDispatcher.getBlockEntities(level) .update(blockEntity); } } diff --git a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java index ecef7d85e..46456acef 100644 --- a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java +++ b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java @@ -20,7 +20,7 @@ public final class FlwUtil { } @Contract("null -> false") - public static boolean canUseInstancing(@Nullable LevelAccessor level) { + public static boolean canUseVisualization(@Nullable LevelAccessor level) { return BackendManager.isOn() && isFlywheelLevel(level); } diff --git a/src/main/java/com/jozufozu/flywheel/util/Lazy.java b/src/main/java/com/jozufozu/flywheel/util/Lazy.java index 2945da562..eb4c5fe7d 100644 --- a/src/main/java/com/jozufozu/flywheel/util/Lazy.java +++ b/src/main/java/com/jozufozu/flywheel/util/Lazy.java @@ -8,7 +8,6 @@ import java.util.function.Supplier; import org.jetbrains.annotations.NotNull; public class Lazy implements Supplier { - private final NonNullSupplier supplier; private T value; diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellVisual.java similarity index 65% rename from src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java rename to src/main/java/com/jozufozu/flywheel/vanilla/BellVisual.java index aa9526224..414aef3f5 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellVisual.java @@ -5,16 +5,16 @@ import java.util.List; 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.struct.InstancePart; -import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.lib.instance.InstanceTypes; +import com.jozufozu.flywheel.lib.instance.OrientedInstance; 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.lib.util.AnimationTickHolder; +import com.jozufozu.flywheel.lib.visual.AbstractBlockEntityVisual; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; @@ -22,21 +22,21 @@ import net.minecraft.client.renderer.blockentity.BellRenderer; import net.minecraft.util.Mth; import net.minecraft.world.level.block.entity.BellBlockEntity; -public class BellInstance extends AbstractBlockEntityInstance implements DynamicInstance { - private static final SimpleLazyModel MODEL = new SimpleLazyModel(BellInstance::createBellModel, Materials.BELL); +public class BellVisual extends AbstractBlockEntityVisual implements DynamicVisual { + private static final SimpleLazyModel BELL_MODEL = new SimpleLazyModel(BellVisual::createBellMesh, Materials.BELL); - private OrientedPart bell; + private OrientedInstance bell; private float lastRingTime = Float.NaN; - public BellInstance(InstanceContext ctx, BellBlockEntity blockEntity) { + public BellVisual(VisualizationContext ctx, BellBlockEntity blockEntity) { super(ctx, blockEntity); } @Override public void init() { bell = createBellInstance().setPivot(0.5f, 0.75f, 0.5f) - .setPosition(getInstancePosition()); + .setPosition(getVisualPosition()); super.init(); } @@ -68,7 +68,7 @@ public class BellInstance extends AbstractBlockEntityInstance i } @Override - public List getCrumblingParts() { + public List getCrumblingInstances() { return List.of(bell); } @@ -77,13 +77,13 @@ public class BellInstance extends AbstractBlockEntityInstance i bell.delete(); } - private OrientedPart createBellInstance() { - return instancerProvider.instancer(StructTypes.ORIENTED, MODEL, RenderStage.AFTER_BLOCK_ENTITIES) + private OrientedInstance createBellInstance() { + return instancerProvider.instancer(InstanceTypes.ORIENTED, BELL_MODEL, RenderStage.AFTER_BLOCK_ENTITIES) .createInstance(); } @NotNull - private static ModelPart createBellModel() { + private static ModelPart createBellMesh() { return ModelPart.builder("bell", 32, 32) .sprite(BellRenderer.BELL_RESOURCE_LOCATION.sprite()) .cuboid() diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestVisual.java similarity index 74% rename from src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java rename to src/main/java/com/jozufozu/flywheel/vanilla/ChestVisual.java index 4e862a238..365390ee0 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestVisual.java @@ -5,17 +5,17 @@ import java.util.List; 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.struct.InstancePart; -import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.lib.instance.InstanceTypes; +import com.jozufozu.flywheel.lib.instance.OrientedInstance; +import com.jozufozu.flywheel.lib.instance.TransformedInstance; 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.lib.struct.TransformedPart; import com.jozufozu.flywheel.lib.util.AnimationTickHolder; +import com.jozufozu.flywheel.lib.visual.AbstractBlockEntityVisual; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; @@ -32,12 +32,12 @@ import net.minecraft.world.level.block.entity.ChestBlockEntity; import net.minecraft.world.level.block.entity.LidBlockEntity; import net.minecraft.world.level.block.state.properties.ChestType; -public class ChestInstance extends AbstractBlockEntityInstance implements DynamicInstance { - private static final BiFunction LID = Util.memoize((type, mat) -> new SimpleLazyModel(() -> createLidModel(type, mat), Materials.CHEST)); - private static final BiFunction BASE = Util.memoize((type, mat) -> new SimpleLazyModel(() -> createBaseModel(type, mat), Materials.CHEST)); +public class ChestVisual extends AbstractBlockEntityVisual implements DynamicVisual { + private static final BiFunction BODY_MODEL_FUNC = Util.memoize((type, mat) -> new SimpleLazyModel(() -> createBodyMesh(type, mat), Materials.CHEST)); + private static final BiFunction LID_MODEL_FUNC = Util.memoize((type, mat) -> new SimpleLazyModel(() -> createLidMesh(type, mat), Materials.CHEST)); - private OrientedPart body; - private TransformedPart lid; + private OrientedInstance body; + private TransformedInstance lid; private Float2FloatFunction lidProgress; private TextureAtlasSprite sprite; @@ -46,7 +46,7 @@ public class ChestInstance extends Abstr private float lastProgress = Float.NaN; - public ChestInstance(InstanceContext ctx, T blockEntity) { + public ChestVisual(VisualizationContext ctx, T blockEntity) { super(ctx, blockEntity); } @@ -58,8 +58,8 @@ public class ChestInstance extends Abstr sprite = Sheets.chooseMaterial(blockEntity, chestType, isChristmas()) .sprite(); - body = baseInstance().setPosition(getInstancePosition()); - lid = lidInstance(); + body = createBodyInstance().setPosition(getVisualPosition()); + lid = createLidInstance(); if (block instanceof AbstractChestBlock chestBlock) { float horizontalAngle = blockState.getValue(ChestBlock.FACING).toYRot(); @@ -95,7 +95,7 @@ public class ChestInstance extends Abstr float angleX = -(progress * ((float) Math.PI / 2F)); lid.loadIdentity() - .translate(getInstancePosition()) + .translate(getVisualPosition()) .translate(0, 9f/16f, 0) .centre() .multiply(baseRotation) @@ -111,7 +111,7 @@ public class ChestInstance extends Abstr } @Override - public List getCrumblingParts() { + public List getCrumblingInstances() { return List.of(body, lid); } @@ -121,18 +121,17 @@ public class ChestInstance extends Abstr lid.delete(); } - private OrientedPart baseInstance() { - return instancerProvider.instancer(StructTypes.ORIENTED, BASE.apply(chestType, sprite), RenderStage.AFTER_BLOCK_ENTITIES) + private OrientedInstance createBodyInstance() { + return instancerProvider.instancer(InstanceTypes.ORIENTED, BODY_MODEL_FUNC.apply(chestType, sprite), RenderStage.AFTER_BLOCK_ENTITIES) .createInstance(); } - private TransformedPart lidInstance() { - return instancerProvider.instancer(StructTypes.TRANSFORMED, LID.apply(chestType, sprite), RenderStage.AFTER_BLOCK_ENTITIES) + private TransformedInstance createLidInstance() { + return instancerProvider.instancer(InstanceTypes.TRANSFORMED, LID_MODEL_FUNC.apply(chestType, sprite), RenderStage.AFTER_BLOCK_ENTITIES) .createInstance(); } - private static ModelPart createBaseModel(ChestType type, TextureAtlasSprite sprite) { - + private static ModelPart createBodyMesh(ChestType type, TextureAtlasSprite sprite) { return switch (type) { case LEFT -> ModelPart.builder("chest_base_left", 64, 64) .sprite(sprite) @@ -159,11 +158,9 @@ public class ChestInstance extends Abstr .endCuboid() .build(); }; - } - private static ModelPart createLidModel(ChestType type, TextureAtlasSprite sprite) { - + private static ModelPart createLidMesh(ChestType type, TextureAtlasSprite sprite) { return switch (type) { case LEFT -> ModelPart.builder("chest_lid_left", 64, 64) .sprite(sprite) @@ -202,7 +199,6 @@ public class ChestInstance extends Abstr .endCuboid() .build(); }; - } public static boolean isChristmas() { diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartVisual.java similarity index 81% rename from src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java rename to src/main/java/com/jozufozu/flywheel/vanilla/MinecartVisual.java index 1e1cc638f..c1a69782a 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartVisual.java @@ -3,19 +3,18 @@ package com.jozufozu.flywheel.vanilla; 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.TickableInstance; -import com.jozufozu.flywheel.api.instance.controller.InstanceContext; -import com.jozufozu.flywheel.api.model.Mesh; -import com.jozufozu.flywheel.lib.instance.AbstractEntityInstance; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visual.TickableVisual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.lib.instance.InstanceTypes; +import com.jozufozu.flywheel.lib.instance.TransformedInstance; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.Models; import com.jozufozu.flywheel.lib.model.SimpleLazyModel; 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.lib.util.AnimationTickHolder; +import com.jozufozu.flywheel.lib.visual.AbstractEntityVisual; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; @@ -25,25 +24,25 @@ import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; -public class MinecartInstance extends AbstractEntityInstance implements DynamicInstance, TickableInstance { - private static final SimpleLazyModel MODEL = new SimpleLazyModel(MinecartInstance::getBodyModel, Materials.MINECART); +public class MinecartVisual extends AbstractEntityVisual implements DynamicVisual, TickableVisual { + private static final SimpleLazyModel BODY_MODEL = new SimpleLazyModel(MinecartVisual::getBodyMesh, Materials.MINECART); private final PoseStack stack = new PoseStack(); - private TransformedPart body; - private TransformedPart contents; + private TransformedInstance body; + private TransformedInstance contents; private BlockState blockState; private boolean active; - public MinecartInstance(InstanceContext ctx, T entity) { + public MinecartVisual(VisualizationContext ctx, T entity) { super(ctx, entity); } @Override public void init() { - body = getBody(); + body = createBodyInstance(); blockState = entity.getDisplayBlockState(); - contents = getContents(); + contents = createContentsInstance(); super.init(); } @@ -60,7 +59,7 @@ public class MinecartInstance extends AbstractEntity if (displayBlockState != blockState) { blockState = displayBlockState; contents.delete(); - contents = getContents(); + contents = createContentsInstance(); if (contents != null) { relight(entity.blockPosition(), contents); } @@ -157,7 +156,7 @@ public class MinecartInstance extends AbstractEntity } } - private TransformedPart getContents() { + private TransformedInstance createContentsInstance() { RenderShape shape = blockState.getRenderShape(); if (shape == RenderShape.ENTITYBLOCK_ANIMATED) { @@ -171,17 +170,17 @@ public class MinecartInstance extends AbstractEntity return null; } - return instancerProvider.instancer(StructTypes.TRANSFORMED, Models.block(blockState), RenderStage.AFTER_ENTITIES) + return instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.block(blockState), RenderStage.AFTER_ENTITIES) .createInstance(); } - private TransformedPart getBody() { - return instancerProvider.instancer(StructTypes.TRANSFORMED, MODEL, RenderStage.AFTER_ENTITIES) + private TransformedInstance createBodyInstance() { + return instancerProvider.instancer(InstanceTypes.TRANSFORMED, BODY_MODEL, RenderStage.AFTER_ENTITIES) .createInstance(); } @NotNull - private static Mesh getBodyModel() { + private static ModelPart getBodyMesh() { int y = -3; return ModelPart.builder("minecart", 64, 32) .cuboid().invertYZ().start(-10, -8, -y).size(20, 16, 2).textureOffset(0, 10).rotateZ((float) Math.PI).rotateX(((float)Math.PI / 2F)).endCuboid() diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxVisual.java similarity index 63% rename from src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java rename to src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxVisual.java index da5c1eb84..f0f586b38 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxVisual.java @@ -4,17 +4,17 @@ import java.util.List; 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.struct.InstancePart; -import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; +import com.jozufozu.flywheel.api.instance.Instance; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.lib.instance.InstanceTypes; +import com.jozufozu.flywheel.lib.instance.TransformedInstance; 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.StructTypes; -import com.jozufozu.flywheel.lib.struct.TransformedPart; import com.jozufozu.flywheel.lib.transform.TransformStack; import com.jozufozu.flywheel.lib.util.AnimationTickHolder; +import com.jozufozu.flywheel.lib.visual.AbstractBlockEntityVisual; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Quaternion; import com.mojang.math.Vector3f; @@ -27,20 +27,19 @@ import net.minecraft.world.item.DyeColor; import net.minecraft.world.level.block.ShulkerBoxBlock; import net.minecraft.world.level.block.entity.ShulkerBoxBlockEntity; -public class ShulkerBoxInstance extends AbstractBlockEntityInstance implements DynamicInstance { - - private static final Function BASE = Util.memoize(it -> new SimpleLazyModel(() -> makeBaseModel(it), Materials.SHULKER)); - private static final Function LID = Util.memoize(it -> new SimpleLazyModel(() -> makeLidModel(it), Materials.SHULKER)); +public class ShulkerBoxVisual extends AbstractBlockEntityVisual implements DynamicVisual { + private static final Function BODY_MODEL_FUNC = Util.memoize(it -> new SimpleLazyModel(() -> createBodyMesh(it), Materials.SHULKER)); + private static final Function LID_MODEL_FUNC = Util.memoize(it -> new SimpleLazyModel(() -> createLidMesh(it), Materials.SHULKER)); private TextureAtlasSprite texture; - private TransformedPart base; - private TransformedPart lid; + private TransformedInstance body; + private TransformedInstance lid; private final PoseStack stack = new PoseStack(); private float lastProgress = Float.NaN; - public ShulkerBoxInstance(InstanceContext ctx, ShulkerBoxBlockEntity blockEntity) { + public ShulkerBoxVisual(VisualizationContext ctx, ShulkerBoxBlockEntity blockEntity) { super(ctx, blockEntity); } @@ -57,18 +56,18 @@ public class ShulkerBoxInstance extends AbstractBlockEntityInstance getCrumblingParts() { - return List.of(base, lid); + public List getCrumblingInstances() { + return List.of(body, lid); } @Override protected void _delete() { - base.delete(); + body.delete(); lid.delete(); } @Override public void updateLight() { - relight(pos, base, lid); + relight(pos, body, lid); } - private TransformedPart makeBaseInstance() { - return instancerProvider.instancer(StructTypes.TRANSFORMED, BASE.apply(texture), RenderStage.AFTER_BLOCK_ENTITIES) + private TransformedInstance createBodyInstance() { + return instancerProvider.instancer(InstanceTypes.TRANSFORMED, BODY_MODEL_FUNC.apply(texture), RenderStage.AFTER_BLOCK_ENTITIES) .createInstance(); } - private TransformedPart makeLidInstance() { - return instancerProvider.instancer(StructTypes.TRANSFORMED, LID.apply(texture), RenderStage.AFTER_BLOCK_ENTITIES) + private TransformedInstance createLidInstance() { + return instancerProvider.instancer(InstanceTypes.TRANSFORMED, LID_MODEL_FUNC.apply(texture), RenderStage.AFTER_BLOCK_ENTITIES) .createInstance(); } - private static ModelPart makeBaseModel(TextureAtlasSprite texture) { + private static ModelPart createBodyMesh(TextureAtlasSprite texture) { return ModelPart.builder("shulker_base", 64, 64) .sprite(texture) .cuboid() @@ -131,7 +130,7 @@ public class ShulkerBoxInstance extends AbstractBlockEntityInstance{@link BlockEntityType#CAMPFIRE} {@link net.minecraft.client.renderer.blockentity.CampfireRenderer CampfireRenderer} * */ -public class VanillaInstances { +public class VanillaVisuals { public static void init() { configure(BlockEntityType.CHEST) .alwaysSkipRender() - .factory(ChestInstance::new) + .factory(ChestVisual::new) .apply(); configure(BlockEntityType.ENDER_CHEST) .alwaysSkipRender() - .factory(ChestInstance::new) + .factory(ChestVisual::new) .apply(); configure(BlockEntityType.TRAPPED_CHEST) .alwaysSkipRender() - .factory(ChestInstance::new) + .factory(ChestVisual::new) .apply(); configure(BlockEntityType.BELL) .alwaysSkipRender() - .factory(BellInstance::new) + .factory(BellVisual::new) .apply(); configure(BlockEntityType.SHULKER_BOX) .alwaysSkipRender() - .factory(ShulkerBoxInstance::new) + .factory(ShulkerBoxVisual::new) .apply(); configure(EntityType.MINECART) - .skipRender(MinecartInstance::shouldSkipRender) - .factory(MinecartInstance::new) + .skipRender(MinecartVisual::shouldSkipRender) + .factory(MinecartVisual::new) .apply(); configure(EntityType.COMMAND_BLOCK_MINECART) - .skipRender(MinecartInstance::shouldSkipRender) - .factory(MinecartInstance::new) + .skipRender(MinecartVisual::shouldSkipRender) + .factory(MinecartVisual::new) .apply(); configure(EntityType.FURNACE_MINECART) - .skipRender(MinecartInstance::shouldSkipRender) - .factory(MinecartInstance::new) + .skipRender(MinecartVisual::shouldSkipRender) + .factory(MinecartVisual::new) .apply(); configure(EntityType.HOPPER_MINECART) - .skipRender(MinecartInstance::shouldSkipRender) - .factory(MinecartInstance::new) + .skipRender(MinecartVisual::shouldSkipRender) + .factory(MinecartVisual::new) .apply(); configure(EntityType.TNT_MINECART) - .skipRender(MinecartInstance::shouldSkipRender) - .factory(MinecartInstance::new) + .skipRender(MinecartVisual::shouldSkipRender) + .factory(MinecartVisual::new) .apply(); } } 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 c149585c4..db8f77f48 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java @@ -10,19 +10,19 @@ import org.joml.Vector3f; import com.jozufozu.flywheel.api.event.ReloadRenderersEvent; import com.jozufozu.flywheel.api.event.RenderStage; -import com.jozufozu.flywheel.api.instance.DynamicInstance; -import com.jozufozu.flywheel.api.instance.EffectInstance; -import com.jozufozu.flywheel.api.instance.TickableInstance; -import com.jozufozu.flywheel.api.instance.controller.InstanceContext; -import com.jozufozu.flywheel.api.instance.effect.Effect; -import com.jozufozu.flywheel.impl.instancing.InstancedRenderDispatcher; +import com.jozufozu.flywheel.api.visual.DynamicVisual; +import com.jozufozu.flywheel.api.visual.Effect; +import com.jozufozu.flywheel.api.visual.EffectVisual; +import com.jozufozu.flywheel.api.visual.TickableVisual; +import com.jozufozu.flywheel.api.visualization.VisualizationContext; +import com.jozufozu.flywheel.impl.visualization.VisualizedRenderDispatcher; import com.jozufozu.flywheel.lib.box.ImmutableBox; import com.jozufozu.flywheel.lib.box.MutableBox; -import com.jozufozu.flywheel.lib.instance.AbstractInstance; +import com.jozufozu.flywheel.lib.instance.InstanceTypes; +import com.jozufozu.flywheel.lib.instance.TransformedInstance; 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.lib.util.AnimationTickHolder; +import com.jozufozu.flywheel.lib.visual.AbstractVisual; import net.minecraft.client.Minecraft; import net.minecraft.core.BlockPos; @@ -35,10 +35,9 @@ import net.minecraftforge.event.TickEvent; // http://www.kfish.org/boids/pseudocode.html public class ExampleEffect implements Effect { - private static final List ALL_EFFECTS = new ArrayList<>(); - private static final int INSTANCE_COUNT = 500; + private static final int VISUAL_COUNT = 500; private static final float SPAWN_RADIUS = 8.0f; private static final float LIMIT_RANGE = 10.0f; private static final float SPEED_LIMIT = 0.1f; @@ -46,7 +45,6 @@ public class ExampleEffect implements Effect { private static final float SIGHT_RANGE = 5; - private static final float COHERENCE = 1f / 60f; private static final float SEPARATION = 0.05f; private static final float ALIGNMENT = 1 / 20f; @@ -60,7 +58,7 @@ public class ExampleEffect implements Effect { private final BlockPos blockPos; private final ImmutableBox volume; - private final List effects; + private final List effects; private final List boids; @@ -69,8 +67,8 @@ public class ExampleEffect implements Effect { this.targetPoint = targetPoint; this.blockPos = new BlockPos(targetPoint.x, targetPoint.y, targetPoint.z); this.volume = MutableBox.from(this.blockPos); - this.effects = new ArrayList<>(INSTANCE_COUNT); - this.boids = new ArrayList<>(INSTANCE_COUNT); + this.effects = new ArrayList<>(VISUAL_COUNT); + this.boids = new ArrayList<>(VISUAL_COUNT); } public static void tick(TickEvent.ClientTickEvent event) { @@ -105,22 +103,22 @@ public class ExampleEffect implements Effect { ExampleEffect effect = new ExampleEffect(level, new Vector3f(x, y, z)); ALL_EFFECTS.add(effect); - InstancedRenderDispatcher.getEffects(level) + VisualizedRenderDispatcher.getEffects(level) .queueAdd(effect); } @Override - public Collection> createInstances(InstanceContext ctx) { + public Collection> createVisuals(VisualizationContext ctx) { effects.clear(); boids.clear(); - for (int i = 0; i < INSTANCE_COUNT; i++) { + for (int i = 0; i < VISUAL_COUNT; i++) { var x = targetPoint.x + level.random.nextFloat(-SPAWN_RADIUS, SPAWN_RADIUS); var y = targetPoint.y + level.random.nextFloat(-SPAWN_RADIUS, SPAWN_RADIUS); var z = targetPoint.z + level.random.nextFloat(-SPAWN_RADIUS, SPAWN_RADIUS); Boid boid = new Boid(x, y, z); boids.add(boid); - effects.add(new BoidInstance(ctx, level, boid)); + effects.add(new BoidVisual(ctx, level, boid)); } return Collections.unmodifiableList(effects); } @@ -238,19 +236,19 @@ public class ExampleEffect implements Effect { } } - public class BoidInstance extends AbstractInstance implements EffectInstance, DynamicInstance, TickableInstance { - + public class BoidVisual extends AbstractVisual implements EffectVisual, DynamicVisual, TickableVisual { private final Boid self; - private TransformedPart instance; - public BoidInstance(InstanceContext ctx, Level level, Boid self) { + private TransformedInstance instance; + + public BoidVisual(VisualizationContext ctx, Level level, Boid self) { super(ctx, level); this.self = self; } @Override public void init() { - instance = instancerProvider.instancer(StructTypes.TRANSFORMED, Models.block(Blocks.SHROOMLIGHT.defaultBlockState()), RenderStage.AFTER_PARTICLES) + instance = instancerProvider.instancer(InstanceTypes.TRANSFORMED, Models.block(Blocks.SHROOMLIGHT.defaultBlockState()), RenderStage.AFTER_PARTICLES) .createInstance(); instance.setBlockLight(15) diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json index 803dee3b5..6f559c065 100644 --- a/src/main/resources/flywheel.mixins.json +++ b/src/main/resources/flywheel.mixins.json @@ -19,13 +19,13 @@ "PausedPartialTickAccessor", "RenderTypeMixin", "VertexFormatMixin", - "instancemanage.ChunkRebuildHooksMixin", - "instancemanage.InstanceAddMixin", - "instancemanage.InstanceRemoveMixin", - "instancemanage.InstanceUpdateMixin", "matrix.Matrix3fAccessor", "matrix.Matrix4fAccessor", - "matrix.PoseStackMixin" + "matrix.PoseStackMixin", + "visualmanage.ChunkRebuildHooksMixin", + "visualmanage.VisualAddMixin", + "visualmanage.VisualRemoveMixin", + "visualmanage.VisualUpdateMixin" ], "injectors": { "defaultRequire": 1