From e6248f502ed27ed447c2aa15a5fbff8c3535924d Mon Sep 17 00:00:00 2001 From: Jozufozu Date: Tue, 4 Apr 2023 21:29:36 -0700 Subject: [PATCH] It's-a me - Lots of plumbing - Storages/InstanceManagers directly reference the Engine - Construct Instances with InstanceContext record - Stores InstancerProvider as well as Vec3i renderOrigin - AbstractInstance stores renderOrigin - InstancerProvider#getOriginCoordinate -> RenderDispatcher#renderOrigin - Update some styling/documentation - Inline InstancingControllerHelper create functions - Use explicit functional interface instead of BiFunction in Controllers --- .../api/backend/RenderDispatcher.java | 4 ++ .../api/instance/TickableInstance.java | 7 ++-- .../BlockEntityInstancingController.java | 6 +-- .../EntityInstancingController.java | 6 +-- .../instance/controller/InstanceContext.java | 16 ++++++++ .../flywheel/api/instance/effect/Effect.java | 4 +- .../flywheel/api/instancer/Instancer.java | 1 - .../api/instancer/InstancerProvider.java | 5 --- .../engine/batching/BatchingEngine.java | 2 +- .../engine/indirect/IndirectEngine.java | 2 +- .../engine/instancing/InstancingEngine.java | 2 +- .../instancing/InstancedRenderDispatcher.java | 2 +- .../manager/BlockEntityInstanceManager.java | 27 ++++++++------ .../manager/EffectInstanceManager.java | 13 ++++--- .../manager/EntityInstanceManager.java | 18 ++++++--- .../instancing/storage/AbstractStorage.java | 8 ++-- .../instancing/storage/One2OneStorage.java | 6 +-- .../instance/AbstractBlockEntityInstance.java | 10 ++--- .../lib/instance/AbstractEntityInstance.java | 19 ++++------ .../lib/instance/AbstractInstance.java | 14 +++++-- .../instance/InstancingControllerHelper.java | 37 ------------------- ...SimpleBlockEntityInstancingController.java | 27 +++++++++----- .../SimpleEntityInstancingController.java | 27 +++++++++----- .../flywheel/vanilla/BellInstance.java | 9 ++--- .../flywheel/vanilla/ChestInstance.java | 12 +++--- .../flywheel/vanilla/MinecartInstance.java | 13 ++----- .../flywheel/vanilla/ShulkerBoxInstance.java | 9 +++-- .../vanilla/effect/ExampleEffect.java | 17 +++++---- 28 files changed, 164 insertions(+), 159 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/api/instance/controller/InstanceContext.java diff --git a/src/main/java/com/jozufozu/flywheel/api/backend/RenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/api/backend/RenderDispatcher.java index 0071261f4..72a8e1560 100644 --- a/src/main/java/com/jozufozu/flywheel/api/backend/RenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/api/backend/RenderDispatcher.java @@ -5,6 +5,7 @@ import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.task.TaskExecutor; import net.minecraft.client.Camera; +import net.minecraft.core.Vec3i; public interface RenderDispatcher { @@ -15,9 +16,12 @@ public interface RenderDispatcher { /** * Maintain the integer origin coordinate to be within a certain distance from the camera in all directions, * preventing floating point precision issues at high coordinates. + * * @return {@code true} if the origin coordinate was changed, {@code false} otherwise. */ boolean maintainOriginCoordinate(Camera camera); + Vec3i renderOrigin(); + void delete(); } diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java b/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java index bc1ddc153..3e8a24ba8 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/TickableInstance.java @@ -22,10 +22,9 @@ import com.jozufozu.flywheel.api.instancer.Instancer; public interface TickableInstance extends Instance { /** - * Called every tick, and after initialization. - *
- * DISPATCHED IN PARALLEL, don't attempt to mutate anything outside of this instance. - *
+ * Called every tick, and after initialization.

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

* {@link Instancer}/{@link InstancedPart} creation/acquisition is safe here. */ void tick(); 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 index e16e20694..c4d32613e 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/controller/BlockEntityInstancingController.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/controller/BlockEntityInstancingController.java @@ -1,7 +1,6 @@ package com.jozufozu.flywheel.api.instance.controller; import com.jozufozu.flywheel.api.instance.BlockEntityInstance; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; import net.minecraft.world.level.block.entity.BlockEntity; @@ -12,11 +11,12 @@ import net.minecraft.world.level.block.entity.BlockEntity; public interface BlockEntityInstancingController { /** * Given a block entity and an instancer manager, constructs an instance for the block entity. - * @param instancerManager The instancer manager to use. + * + * @param ctx Context for creating an Instance. * @param blockEntity The block entity to construct an instance for. * @return The instance. */ - BlockEntityInstance createInstance(InstancerProvider instancerManager, T blockEntity); + BlockEntityInstance createInstance(InstanceContext ctx, T blockEntity); /** * Checks if the given block entity should not be rendered normally. 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 index a9278e6f7..20eb3e149 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/controller/EntityInstancingController.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/controller/EntityInstancingController.java @@ -1,7 +1,6 @@ package com.jozufozu.flywheel.api.instance.controller; import com.jozufozu.flywheel.api.instance.EntityInstance; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; import net.minecraft.world.entity.Entity; @@ -12,11 +11,12 @@ import net.minecraft.world.entity.Entity; public interface EntityInstancingController { /** * Given an entity and an instancer manager, constructs an instance for the entity. - * @param instancerManager The instancer manager to use. + * + * @param ctx Context for creating an Instance. * @param entity The entity to construct an instance for. * @return The instance. */ - EntityInstance createInstance(InstancerProvider instancerManager, T entity); + EntityInstance createInstance(InstanceContext ctx, T entity); /** * Checks if the given entity should not render normally. 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 new file mode 100644 index 000000000..b8bd8ff88 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/api/instance/controller/InstanceContext.java @@ -0,0 +1,16 @@ +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/effect/Effect.java b/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java index 96cde3f0b..16cb49e3c 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/effect/Effect.java @@ -3,8 +3,8 @@ package com.jozufozu.flywheel.api.instance.effect; import java.util.Collection; import com.jozufozu.flywheel.api.instance.Instance; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; +import com.jozufozu.flywheel.api.instance.controller.InstanceContext; public interface Effect { - Collection createInstances(InstancerProvider instancerManager); + Collection createInstances(InstanceContext ctx); } diff --git a/src/main/java/com/jozufozu/flywheel/api/instancer/Instancer.java b/src/main/java/com/jozufozu/flywheel/api/instancer/Instancer.java index 8e2a384eb..58ef8a8f7 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instancer/Instancer.java +++ b/src/main/java/com/jozufozu/flywheel/api/instancer/Instancer.java @@ -26,7 +26,6 @@ public interface Instancer { /** * Copy a data from another Instancer to this. - * * This has the effect of swapping out one model for another. * @param inOther the data associated with a different model. */ diff --git a/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java b/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java index 92677804f..f9317ebbf 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java +++ b/src/main/java/com/jozufozu/flywheel/api/instancer/InstancerProvider.java @@ -4,8 +4,6 @@ import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.struct.StructType; -import net.minecraft.core.Vec3i; - 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. @@ -13,7 +11,4 @@ public interface InstancerProvider { * @return An instancer for the given struct type, model, and render stage. */ Instancer getInstancer(StructType type, Model model, RenderStage stage); - - // TODO: this method does not belong in this interface - Vec3i getOriginCoordinate(); } 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 91f4c688d..2c1b06a22 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 @@ -90,7 +90,7 @@ public class BatchingEngine implements Engine { } @Override - public Vec3i getOriginCoordinate() { + public Vec3i renderOrigin() { return BlockPos.ZERO; } 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 ce4adfefc..1fbd843fc 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 @@ -110,7 +110,7 @@ public class IndirectEngine implements Engine { } @Override - public Vec3i getOriginCoordinate() { + public Vec3i renderOrigin() { return originCoordinate; } 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 d799ee70c..197349828 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 @@ -155,7 +155,7 @@ public class InstancingEngine implements Engine { } @Override - public Vec3i getOriginCoordinate() { + public Vec3i renderOrigin() { return originCoordinate; } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java index ffee63a77..ecea90a82 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java @@ -128,6 +128,6 @@ public class InstancedRenderDispatcher { } public static Vec3i getOriginCoordinate(ClientLevel level) { - return instanceWorlds.get(level).engine.getOriginCoordinate(); + return instanceWorlds.get(level).engine.renderOrigin(); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/BlockEntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/BlockEntityInstanceManager.java index 821f10bd2..7a31ed9fa 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/BlockEntityInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/BlockEntityInstanceManager.java @@ -4,9 +4,11 @@ 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.instancer.InstancerProvider; +import com.jozufozu.flywheel.api.instance.controller.InstanceContext; +import com.jozufozu.flywheel.api.instance.controller.InstancingControllerRegistry; import com.jozufozu.flywheel.backend.BackendUtil; import com.jozufozu.flywheel.backend.instancing.storage.One2OneStorage; import com.jozufozu.flywheel.backend.instancing.storage.Storage; @@ -22,8 +24,8 @@ import net.minecraft.world.level.block.entity.BlockEntity; public class BlockEntityInstanceManager extends InstanceManager { private final BlockEntityStorage storage; - public BlockEntityInstanceManager(InstancerProvider instancerManager) { - storage = new BlockEntityStorage(instancerManager); + public BlockEntityInstanceManager(Engine engine) { + storage = new BlockEntityStorage(engine); } @Override @@ -72,21 +74,24 @@ public class BlockEntityInstanceManager extends InstanceManager { private static class BlockEntityStorage extends One2OneStorage { private final Long2ObjectMap> posLookup = new Long2ObjectOpenHashMap<>(); - public BlockEntityStorage(InstancerProvider instancerManager) { - super(instancerManager); + public BlockEntityStorage(Engine engine) { + super(engine); } @Override @Nullable protected Instance createRaw(BlockEntity obj) { - BlockEntityInstance instance = InstancingControllerHelper.createInstance(instancerManager, obj); - - if (instance != null) { - BlockPos blockPos = obj.getBlockPos(); - posLookup.put(blockPos.asLong(), instance); + var controller = InstancingControllerRegistry.getController(InstancingControllerHelper.getType(obj)); + if (controller == null) { + return null; } - return instance; + var out = controller.createInstance(new InstanceContext(engine, engine.renderOrigin()), obj); + + BlockPos blockPos = obj.getBlockPos(); + posLookup.put(blockPos.asLong(), out); + + return out; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EffectInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EffectInstanceManager.java index 5d2ccdc72..52447562c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EffectInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EffectInstanceManager.java @@ -4,17 +4,18 @@ import java.util.ArrayList; 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; +import com.jozufozu.flywheel.api.instance.controller.InstanceContext; import com.jozufozu.flywheel.api.instance.effect.Effect; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; import com.jozufozu.flywheel.backend.instancing.storage.AbstractStorage; import com.jozufozu.flywheel.backend.instancing.storage.Storage; public class EffectInstanceManager extends InstanceManager { private final EffectStorage storage; - public EffectInstanceManager(InstancerProvider instancerManager) { - storage = new EffectStorage<>(instancerManager); + public EffectInstanceManager(Engine engine) { + storage = new EffectStorage<>(engine); } @Override @@ -30,8 +31,8 @@ public class EffectInstanceManager extends InstanceManager { private static class EffectStorage extends AbstractStorage { private final Multimap instances; - public EffectStorage(InstancerProvider manager) { - super(manager); + public EffectStorage(Engine engine) { + super(engine); this.instances = HashMultimap.create(); } @@ -100,7 +101,7 @@ public class EffectInstanceManager extends InstanceManager { } private void create(T obj) { - var instances = obj.createInstances(instancerManager); + var instances = obj.createInstances(new InstanceContext(engine, engine.renderOrigin())); this.instances.putAll(obj, instances); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EntityInstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EntityInstanceManager.java index db513a79b..9b3ba443f 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EntityInstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/manager/EntityInstanceManager.java @@ -2,8 +2,10 @@ package com.jozufozu.flywheel.backend.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.instancer.InstancerProvider; +import com.jozufozu.flywheel.api.instance.controller.InstanceContext; +import com.jozufozu.flywheel.api.instance.controller.InstancingControllerRegistry; import com.jozufozu.flywheel.backend.BackendUtil; import com.jozufozu.flywheel.backend.instancing.storage.One2OneStorage; import com.jozufozu.flywheel.backend.instancing.storage.Storage; @@ -15,8 +17,8 @@ import net.minecraft.world.level.Level; public class EntityInstanceManager extends InstanceManager { private final EntityStorage storage; - public EntityInstanceManager(InstancerProvider instancerManager) { - storage = new EntityStorage(instancerManager); + public EntityInstanceManager(Engine engine) { + storage = new EntityStorage(engine); } @Override @@ -40,14 +42,18 @@ public class EntityInstanceManager extends InstanceManager { } private static class EntityStorage extends One2OneStorage { - public EntityStorage(InstancerProvider instancerManager) { - super(instancerManager); + public EntityStorage(Engine engine) { + super(engine); } @Override @Nullable protected Instance createRaw(Entity obj) { - return InstancingControllerHelper.createInstance(instancerManager, obj); + var controller = InstancingControllerRegistry.getController(InstancingControllerHelper.getType(obj)); + if (controller == null) { + return null; + } + return controller.createInstance(new InstanceContext(engine, engine.renderOrigin()), obj); } } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/AbstractStorage.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/AbstractStorage.java index 42daba0d4..be0ab9e82 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/AbstractStorage.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/AbstractStorage.java @@ -3,18 +3,18 @@ package com.jozufozu.flywheel.backend.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; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; public abstract class AbstractStorage implements Storage { - protected final InstancerProvider instancerManager; + protected final Engine engine; protected final List tickableInstances = new ArrayList<>(); protected final List dynamicInstances = new ArrayList<>(); - protected AbstractStorage(InstancerProvider instancerManager) { - this.instancerManager = instancerManager; + protected AbstractStorage(Engine engine) { + this.engine = engine; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/One2OneStorage.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/One2OneStorage.java index f75eb8b88..af9f239d1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/One2OneStorage.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/storage/One2OneStorage.java @@ -5,14 +5,14 @@ import java.util.Map; import org.jetbrains.annotations.Nullable; +import com.jozufozu.flywheel.api.backend.Engine; import com.jozufozu.flywheel.api.instance.Instance; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; public abstract class One2OneStorage extends AbstractStorage { private final Map instances; - public One2OneStorage(InstancerProvider instancerManager) { - super(instancerManager); + public One2OneStorage(Engine engine) { + super(engine); this.instances = new HashMap<>(); } diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java index 97ddc0d10..15378291c 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractBlockEntityInstance.java @@ -8,8 +8,8 @@ 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.api.instancer.InstancedPart; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; import com.jozufozu.flywheel.backend.instancing.manager.BlockEntityInstanceManager; import com.jozufozu.flywheel.lib.box.ImmutableBox; import com.jozufozu.flywheel.lib.box.MutableBox; @@ -42,12 +42,12 @@ public abstract class AbstractBlockEntityInstance extends protected final BlockPos instancePos; protected final BlockState blockState; - public AbstractBlockEntityInstance(InstancerProvider instancerManager, T blockEntity) { - super(instancerManager, blockEntity.getLevel()); + public AbstractBlockEntityInstance(InstanceContext ctx, T blockEntity) { + super(ctx, blockEntity.getLevel()); this.blockEntity = blockEntity; this.pos = blockEntity.getBlockPos(); this.blockState = blockEntity.getBlockState(); - this.instancePos = pos.subtract(instancerManager.getOriginCoordinate()); + this.instancePos = pos.subtract(renderOrigin); } @Override @@ -82,7 +82,7 @@ public abstract class AbstractBlockEntityInstance extends * represents should be rendered at to appear in the correct location. */ public BlockPos getInstancePosition() { - return pos.subtract(instancerManager.getOriginCoordinate()); + return pos.subtract(renderOrigin); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java index 50866851f..7d2658abd 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractEntityInstance.java @@ -5,13 +5,12 @@ 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.instancer.InstancerProvider; +import com.jozufozu.flywheel.api.instance.controller.InstanceContext; import com.jozufozu.flywheel.backend.instancing.manager.BlockEntityInstanceManager; import com.jozufozu.flywheel.lib.box.MutableBox; import com.jozufozu.flywheel.lib.light.TickingLightListener; import com.mojang.math.Vector3f; -import net.minecraft.core.Vec3i; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.block.entity.BlockEntity; @@ -38,8 +37,8 @@ public abstract class AbstractEntityInstance extends AbstractI protected final E entity; protected final MutableBox bounds; - public AbstractEntityInstance(InstancerProvider instancerManager, E entity) { - super(instancerManager, entity.level); + public AbstractEntityInstance(InstanceContext ctx, E entity) { + super(ctx, entity.level); this.entity = entity; bounds = MutableBox.from(entity.getBoundingBox()); } @@ -53,7 +52,9 @@ public abstract class AbstractEntityInstance extends AbstractI public boolean tickLightListener() { AABB boundsNow = entity.getBoundingBox(); - if (bounds.sameAs(boundsNow)) return false; + if (bounds.sameAs(boundsNow)) { + return false; + } bounds.assign(boundsNow); @@ -71,8 +72,7 @@ public abstract class AbstractEntityInstance extends AbstractI */ public Vector3f getInstancePosition() { Vec3 pos = entity.position(); - Vec3i origin = instancerManager.getOriginCoordinate(); - return new Vector3f((float) (pos.x - origin.getX()), (float) (pos.y - origin.getY()), (float) (pos.z - origin.getZ())); + return new Vector3f((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ())); } /** @@ -84,10 +84,7 @@ public abstract class AbstractEntityInstance extends AbstractI */ public Vector3f getInstancePosition(float partialTicks) { Vec3 pos = entity.position(); - Vec3i origin = instancerManager.getOriginCoordinate(); - return new Vector3f( - (float) (Mth.lerp(partialTicks, entity.xOld, pos.x) - origin.getX()), - (float) (Mth.lerp(partialTicks, entity.yOld, pos.y) - origin.getY()), (float) (Mth.lerp(partialTicks, entity.zOld, pos.z) - origin.getZ())); + 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())); } @Override 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 b917ef835..6e01449c4 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/AbstractInstance.java @@ -4,6 +4,7 @@ import java.util.Arrays; 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.FlatLit; import com.jozufozu.flywheel.api.instancer.InstancerProvider; import com.jozufozu.flywheel.lib.light.LightListener; @@ -11,23 +12,28 @@ 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 AbstractInstance implements Instance, LightListener { - protected final InstancerProvider instancerManager; public final Level level; + public final Vec3i renderOrigin; + + protected final InstancerProvider instancerManager; protected boolean deleted = false; - public AbstractInstance(InstancerProvider instancerManager, Level level) { - this.instancerManager = instancerManager; + public AbstractInstance(InstanceContext ctx, Level level) { + this.instancerManager = ctx.instancerProvider(); + this.renderOrigin = ctx.renderOrigin(); this.level = level; } @Override public void init() { updateLight(); - LightUpdater.get(level).addListener(this); + LightUpdater.get(level) + .addListener(this); } @Override diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/InstancingControllerHelper.java b/src/main/java/com/jozufozu/flywheel/lib/instance/InstancingControllerHelper.java index 57fb789de..733918ad1 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/InstancingControllerHelper.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/InstancingControllerHelper.java @@ -1,13 +1,8 @@ package com.jozufozu.flywheel.lib.instance; -import org.jetbrains.annotations.Nullable; - -import com.jozufozu.flywheel.api.instance.BlockEntityInstance; -import com.jozufozu.flywheel.api.instance.EntityInstance; 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 com.jozufozu.flywheel.api.instancer.InstancerProvider; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; @@ -35,38 +30,6 @@ public final class InstancingControllerHelper { return InstancingControllerRegistry.getController(type) != null; } - /** - * Creates an instance for the given block entity, if possible. - * @param instancerManager The instancer manager to use. - * @param blockEntity The block entity to create an instance of. - * @param The type of the block entity. - * @return An instance of the block entity, or {@code null} if the block entity cannot be instanced. - */ - @Nullable - public static BlockEntityInstance createInstance(InstancerProvider instancerManager, T blockEntity) { - BlockEntityInstancingController controller = InstancingControllerRegistry.getController(getType(blockEntity)); - if (controller == null) { - return null; - } - return controller.createInstance(instancerManager, blockEntity); - } - - /** - * Creates an instance for the given entity, if possible. - * @param instancerManager The instancer manager to use. - * @param entity The entity to create an instance of. - * @param The type of the entity. - * @return An instance of the entity, or {@code null} if the entity cannot be instanced. - */ - @Nullable - public static EntityInstance createInstance(InstancerProvider instancerManager, T entity) { - EntityInstancingController controller = InstancingControllerRegistry.getController(getType(entity)); - if (controller == null) { - return null; - } - return controller.createInstance(instancerManager, entity); - } - /** * Checks if the given block entity is instanced and should not be rendered normally. * @param blockEntity The block entity to check. diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java index 3a03e7f2c..3fc0f4127 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleBlockEntityInstancingController.java @@ -1,29 +1,30 @@ package com.jozufozu.flywheel.lib.instance; import java.util.Objects; -import java.util.function.BiFunction; 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 com.jozufozu.flywheel.api.instancer.InstancerProvider; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; public class SimpleBlockEntityInstancingController implements BlockEntityInstancingController { - protected BiFunction> instanceFactory; + protected Factory instanceFactory; protected Predicate skipRender; - public SimpleBlockEntityInstancingController(BiFunction> instanceFactory, Predicate skipRender) { + public SimpleBlockEntityInstancingController(Factory instanceFactory, Predicate skipRender) { this.instanceFactory = instanceFactory; this.skipRender = skipRender; } @Override - public BlockEntityInstance createInstance(InstancerProvider instancerManager, T blockEntity) { - return instanceFactory.apply(instancerManager, blockEntity); + public BlockEntityInstance createInstance(InstanceContext ctx, T blockEntity) { + return instanceFactory.create(ctx, blockEntity); } @Override @@ -33,21 +34,28 @@ public class SimpleBlockEntityInstancingController implem /** * 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. + * @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 BiFunction> instanceFactory; + protected Factory instanceFactory; protected Predicate skipRender; public BlockEntityConfig(BlockEntityType type) { @@ -56,10 +64,11 @@ public class SimpleBlockEntityInstancingController implem /** * Sets the instance factory for the block entity. + * * @param instanceFactory The instance factory. * @return {@code this} */ - public BlockEntityConfig factory(BiFunction> instanceFactory) { + public BlockEntityConfig factory(Factory instanceFactory) { this.instanceFactory = instanceFactory; return this; } diff --git a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java index b65025165..b8256bb54 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java +++ b/src/main/java/com/jozufozu/flywheel/lib/instance/SimpleEntityInstancingController.java @@ -1,29 +1,30 @@ package com.jozufozu.flywheel.lib.instance; import java.util.Objects; -import java.util.function.BiFunction; 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 com.jozufozu.flywheel.api.instancer.InstancerProvider; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; public class SimpleEntityInstancingController implements EntityInstancingController { - protected BiFunction> instanceFactory; + protected Factory instanceFactory; protected Predicate skipRender; - public SimpleEntityInstancingController(BiFunction> instanceFactory, Predicate skipRender) { + public SimpleEntityInstancingController(Factory instanceFactory, Predicate skipRender) { this.instanceFactory = instanceFactory; this.skipRender = skipRender; } @Override - public EntityInstance createInstance(InstancerProvider instancerManager, T entity) { - return instanceFactory.apply(instancerManager, entity); + public EntityInstance createInstance(InstanceContext ctx, T entity) { + return instanceFactory.create(ctx, entity); } @Override @@ -33,21 +34,28 @@ public class SimpleEntityInstancingController implements Entit /** * 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. + * @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 BiFunction> instanceFactory; + protected Factory instanceFactory; protected Predicate skipRender; public EntityConfig(EntityType type) { @@ -56,10 +64,11 @@ public class SimpleEntityInstancingController implements Entit /** * Sets the instance factory for the entity. + * * @param instanceFactory The instance factory. * @return {@code this} */ - public EntityConfig factory(BiFunction> instanceFactory) { + public EntityConfig factory(Factory instanceFactory) { this.instanceFactory = instanceFactory; return this; } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java index 05c3d3529..9764b77a8 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/BellInstance.java @@ -7,8 +7,8 @@ import org.jetbrains.annotations.NotNull; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.controller.InstanceContext; import com.jozufozu.flywheel.api.instancer.InstancedPart; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.SimpleLazyModel; @@ -31,11 +31,10 @@ public class BellInstance extends AbstractBlockEntityInstance i private float lastRingTime = Float.NaN; - public BellInstance(InstancerProvider instancerManager, BellBlockEntity blockEntity) { - super(instancerManager, blockEntity); + public BellInstance(InstanceContext ctx, BellBlockEntity blockEntity) { + super(ctx, blockEntity); - bell = createBellInstance() - .setPivot(0.5f, 0.75f, 0.5f) + bell = createBellInstance().setPivot(0.5f, 0.75f, 0.5f) .setPosition(getInstancePosition()); } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index 57556627e..857954130 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -9,8 +9,8 @@ import org.jetbrains.annotations.NotNull; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.controller.InstanceContext; import com.jozufozu.flywheel.api.instancer.InstancedPart; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.SimpleLazyModel; @@ -51,16 +51,16 @@ public class ChestInstance extends Abstr private float lastProgress = Float.NaN; - public ChestInstance(InstancerProvider instancerManager, T blockEntity) { - super(instancerManager, blockEntity); + public ChestInstance(InstanceContext ctx, T blockEntity) { + super(ctx, blockEntity); Block block = blockState.getBlock(); chestType = blockState.hasProperty(ChestBlock.TYPE) ? blockState.getValue(ChestBlock.TYPE) : ChestType.SINGLE; - sprite = Sheets.chooseMaterial(blockEntity, chestType, isChristmas()).sprite(); + sprite = Sheets.chooseMaterial(blockEntity, chestType, isChristmas()) + .sprite(); - body = baseInstance() - .setPosition(getInstancePosition()); + body = baseInstance().setPosition(getInstancePosition()); lid = lidInstance(); if (block instanceof AbstractChestBlock chestBlock) { diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java index 1c7d8a008..b042fcfe5 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartInstance.java @@ -5,7 +5,7 @@ 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.instancer.InstancerProvider; +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.lib.material.Materials; @@ -19,7 +19,6 @@ import com.jozufozu.flywheel.util.AnimationTickHolder; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Vector3f; -import net.minecraft.core.Vec3i; import net.minecraft.util.Mth; import net.minecraft.world.entity.vehicle.AbstractMinecart; import net.minecraft.world.level.block.RenderShape; @@ -37,8 +36,8 @@ public class MinecartInstance extends AbstractEntity private BlockState blockState; private boolean active; - public MinecartInstance(InstancerProvider instancerManager, T entity) { - super(instancerManager, entity); + public MinecartInstance(InstanceContext ctx, T entity) { + super(ctx, entity); body = getBody(); blockState = entity.getDisplayBlockState(); @@ -75,11 +74,7 @@ public class MinecartInstance extends AbstractEntity stack.setIdentity(); float pt = AnimationTickHolder.getPartialTicks(); - Vec3i originCoordinate = instancerManager.getOriginCoordinate(); - tstack.translate( - Mth.lerp(pt, entity.xOld, entity.getX()) - originCoordinate.getX(), - Mth.lerp(pt, entity.yOld, entity.getY()) - originCoordinate.getY(), - Mth.lerp(pt, entity.zOld, entity.getZ()) - originCoordinate.getZ()); + tstack.translate(Mth.lerp(pt, entity.xOld, entity.getX()) - renderOrigin.getX(), Mth.lerp(pt, entity.yOld, entity.getY()) - renderOrigin.getY(), Mth.lerp(pt, entity.zOld, entity.getZ()) - renderOrigin.getZ()); float yaw = Mth.lerp(pt, entity.yRotO, entity.getYRot()); diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java index a11f01c9b..2aefef791 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxInstance.java @@ -6,8 +6,8 @@ import java.util.function.Function; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.DynamicInstance; +import com.jozufozu.flywheel.api.instance.controller.InstanceContext; import com.jozufozu.flywheel.api.instancer.InstancedPart; -import com.jozufozu.flywheel.api.instancer.InstancerProvider; import com.jozufozu.flywheel.lib.instance.AbstractBlockEntityInstance; import com.jozufozu.flywheel.lib.material.Materials; import com.jozufozu.flywheel.lib.model.SimpleLazyModel; @@ -41,14 +41,15 @@ public class ShulkerBoxInstance extends AbstractBlockEntityInstance effects; + private final List effects; private final List boids; @@ -109,7 +110,7 @@ public class ExampleEffect implements Effect { } @Override - public Collection createInstances(InstancerProvider instancerManager) { + public Collection createInstances(InstanceContext ctx) { effects.clear(); boids.clear(); for (int i = 0; i < INSTANCE_COUNT; i++) { @@ -119,7 +120,7 @@ public class ExampleEffect implements Effect { Boid boid = new Boid(x, y, z); boids.add(boid); - effects.add(new Instance(instancerManager, level, boid)); + effects.add(new BoidInstance(ctx, level, boid)); } return Collections.unmodifiableList(effects); } @@ -237,13 +238,13 @@ public class ExampleEffect implements Effect { } } - public class Instance extends AbstractInstance implements DynamicInstance, TickableInstance { + public class BoidInstance extends AbstractInstance implements DynamicInstance, TickableInstance { private final Boid self; TransformedPart instance; - public Instance(InstancerProvider instancerManager, Level level, Boid self) { - super(instancerManager, level); + public BoidInstance(InstanceContext ctx, Level level, Boid self) { + super(ctx, level); this.self = self; } @@ -280,7 +281,7 @@ public class ExampleEffect implements Effect { var z = Mth.lerp(partialTicks, self.lastPosition.z, self.position.z); instance.loadIdentity() - .translateBack(instancerManager.getOriginCoordinate()) + .translateBack(renderOrigin) .translate(x, y, z) .scale(RENDER_SCALE); }