implements InstancingEngine.OriginShift
}
}
- protected boolean shouldFrameUpdate(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
- int dX = worldPos.getX() - cX;
- int dY = worldPos.getY() - cY;
- int dZ = worldPos.getZ() - cZ;
-
- // is it more than 2 blocks behind the camera?
- int dist = 2;
- float dot = (dX + lookX * dist) * lookX + (dY + lookY * dist) * lookY + (dZ + lookZ * dist) * lookZ;
- if (dot < 0) return false;
-
- return (frame % getUpdateDivisor(dX, dY, dZ)) == 0;
- }
-
- // 1 followed by the prime numbers
- private static final int[] divisorSequence = new int[] { 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
- protected int getUpdateDivisor(int dX, int dY, int dZ) {
- int dSq = dX * dX + dY * dY + dZ * dZ;
-
- int i = (dSq / 2048);
-
- return divisorSequence[Mth.clamp(i, 0, divisorSequence.length - 1)];
- }
-
protected void addInternal(T obj) {
if (!Backend.isOn()) return;
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 e1a4eb904..ebf6a8e56 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java
@@ -4,6 +4,8 @@ import java.util.List;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.backend.Backend;
+import com.jozufozu.flywheel.config.BooleanConfig;
+import com.jozufozu.flywheel.config.FlwConfig;
import com.jozufozu.flywheel.event.BeginFrameEvent;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.event.RenderLayerEvent;
@@ -123,6 +125,7 @@ public class InstancedRenderDispatcher {
if (Backend.isOn()) {
InstanceWorld instanceWorld = instanceWorlds.get(Minecraft.getInstance().level);
+ debug.add("Update limiting: " + BooleanConfig.boolToText(FlwConfig.get().limitUpdates()).getString());
debug.add("B: " + instanceWorld.blockEntityInstanceManager.getObjectCount() + ", E: " + instanceWorld.entityInstanceManager.getObjectCount());
instanceWorld.engine.addDebugInfo(debug);
} else {
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
index 42cca0e13..e3efc8a71 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
@@ -154,9 +154,9 @@ public class InstancingEngine implements Engine {
@Override
public void addDebugInfo(List info) {
info.add("GL33 Instanced Arrays");
- info.add("Origin: " + originCoordinate.getX() + ", " + originCoordinate.getY() + ", " + originCoordinate.getZ());
info.add("Instances: " + getGroupsToRender(null).mapToInt(InstancedMaterialGroup::getInstanceCount).sum());
info.add("Vertices: " + getGroupsToRender(null).mapToInt(InstancedMaterialGroup::getVertexCount).sum());
+ info.add("Origin: " + originCoordinate.getX() + ", " + originCoordinate.getY() + ", " + originCoordinate.getZ());
}
@FunctionalInterface
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/BandedPrimeLimiter.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/BandedPrimeLimiter.java
new file mode 100644
index 000000000..278f5ff1e
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/BandedPrimeLimiter.java
@@ -0,0 +1,28 @@
+package com.jozufozu.flywheel.backend.instancing.ratelimit;
+
+import net.minecraft.util.Mth;
+
+public class BandedPrimeLimiter implements DistanceUpdateLimiter {
+ // 1 followed by the prime numbers
+ private static final int[] divisorSequence = new int[] { 1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31 };
+
+ private int tickCount = 0;
+
+ @Override
+ public void tick() {
+ tickCount++;
+ }
+
+ @Override
+ public boolean shouldUpdate(int dX, int dY, int dZ) {
+ return (tickCount % getUpdateDivisor(dX, dY, dZ)) == 0;
+ }
+
+ protected int getUpdateDivisor(int dX, int dY, int dZ) {
+ int dSq = dX * dX + dY * dY + dZ * dZ;
+
+ int i = (dSq / 2048);
+
+ return divisorSequence[Mth.clamp(i, 0, divisorSequence.length - 1)];
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/DistanceUpdateLimiter.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/DistanceUpdateLimiter.java
new file mode 100644
index 000000000..7fb3ceff6
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/DistanceUpdateLimiter.java
@@ -0,0 +1,20 @@
+package com.jozufozu.flywheel.backend.instancing.ratelimit;
+
+/**
+ * Interface for rate-limiting updates based on an object's distance from the camera.
+ */
+public interface DistanceUpdateLimiter {
+ /**
+ * Call this before every update.
+ */
+ void tick();
+
+ /**
+ * Check to see if an object at the given position relative to the camera should be updated.
+ * @param dX The X distance from the camera.
+ * @param dY The Y distance from the camera.
+ * @param dZ The Z distance from the camera.
+ * @return {@code true} if the object should be updated, {@code false} otherwise.
+ */
+ boolean shouldUpdate(int dX, int dY, int dZ);
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/NonLimiter.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/NonLimiter.java
new file mode 100644
index 000000000..ea5afb230
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/ratelimit/NonLimiter.java
@@ -0,0 +1,13 @@
+package com.jozufozu.flywheel.backend.instancing.ratelimit;
+
+public class NonLimiter implements DistanceUpdateLimiter {
+ @Override
+ public void tick() {
+ // noop
+ }
+
+ @Override
+ public boolean shouldUpdate(int dX, int dY, int dZ) {
+ return true;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java b/src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java
index 4014fe5bd..2cdf578b6 100644
--- a/src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java
+++ b/src/main/java/com/jozufozu/flywheel/config/BooleanConfig.java
@@ -1,7 +1,8 @@
package com.jozufozu.flywheel.config;
import java.util.function.Consumer;
-import java.util.function.Supplier;
+
+import com.jozufozu.flywheel.backend.Backend;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
@@ -9,20 +10,36 @@ import net.minecraft.client.player.LocalPlayer;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TextComponent;
-import net.minecraftforge.api.distmarker.Dist;
-import net.minecraftforge.api.distmarker.OnlyIn;
public enum BooleanConfig {
- NORMAL_OVERLAY(() -> BooleanConfig::normalOverlay),
- ;
+ NORMAL_OVERLAY(BooleanConfig::normalOverlay),
+ LIMIT_UPDATES(BooleanConfig::limitUpdates);
- final Supplier> receiver;
+ final Consumer receiver;
- BooleanConfig(Supplier> receiver) {
+ BooleanConfig(Consumer receiver) {
this.receiver = receiver;
}
- @OnlyIn(Dist.CLIENT)
+ private static void limitUpdates(BooleanDirective booleanDirective) {
+ LocalPlayer player = Minecraft.getInstance().player;
+ if (player == null || booleanDirective == null) return;
+
+ if (booleanDirective == BooleanDirective.DISPLAY) {
+ Component text = new TextComponent("Update limiting is currently: ").append(boolToText(FlwConfig.get().limitUpdates()));
+ player.displayClientMessage(text, false);
+ return;
+ }
+
+ FlwConfig.get().client.limitUpdates.set(booleanDirective.get());
+
+ Component text = boolToText(FlwConfig.get().limitUpdates()).append(new TextComponent(" update limiting.").withStyle(ChatFormatting.WHITE));
+
+ player.displayClientMessage(text, false);
+
+ Backend.reloadWorldRenderers();
+ }
+
private static void normalOverlay(BooleanDirective state) {
LocalPlayer player = Minecraft.getInstance().player;
if (player == null || state == null) return;
@@ -40,7 +57,7 @@ public enum BooleanConfig {
player.displayClientMessage(text, false);
}
- private static MutableComponent boolToText(boolean b) {
+ public static MutableComponent boolToText(boolean b) {
return b ? new TextComponent("enabled").withStyle(ChatFormatting.DARK_GREEN) : new TextComponent("disabled").withStyle(ChatFormatting.RED);
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/config/BooleanConfigCommand.java b/src/main/java/com/jozufozu/flywheel/config/BooleanConfigCommand.java
index 9c690af30..d3be59e10 100644
--- a/src/main/java/com/jozufozu/flywheel/config/BooleanConfigCommand.java
+++ b/src/main/java/com/jozufozu/flywheel/config/BooleanConfigCommand.java
@@ -20,17 +20,17 @@ public class BooleanConfigCommand {
public ArgumentBuilder register() {
return Commands.literal(name)
.executes(context -> {
- value.receiver.get().accept(BooleanDirective.DISPLAY);
+ value.receiver.accept(BooleanDirective.DISPLAY);
return Command.SINGLE_SUCCESS;
})
.then(Commands.literal("on")
.executes(context -> {
- value.receiver.get().accept(BooleanDirective.TRUE);
+ value.receiver.accept(BooleanDirective.TRUE);
return Command.SINGLE_SUCCESS;
}))
.then(Commands.literal("off")
.executes(context -> {
- value.receiver.get().accept(BooleanDirective.FALSE);
+ value.receiver.accept(BooleanDirective.FALSE);
return Command.SINGLE_SUCCESS;
}));
}
diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java
index 5d945cc26..018e8efce 100644
--- a/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java
+++ b/src/main/java/com/jozufozu/flywheel/config/FlwCommands.java
@@ -13,15 +13,20 @@ public class FlwCommands {
CommandDispatcher dispatcher = event.getDispatcher();
dispatcher.register(Commands.literal("flywheel")
- .then(debugCommand())
- .then(backendCommand())
+ .then(debugNormalsCommand())
+ .then(backendCommand())
+ .then(limitUpdatesCommand())
);
}
- private static ArgumentBuilder debugCommand() {
+ private static ArgumentBuilder debugNormalsCommand() {
return new BooleanConfigCommand("debugNormals", BooleanConfig.NORMAL_OVERLAY).register();
}
+ private static ArgumentBuilder limitUpdatesCommand() {
+ return new BooleanConfigCommand("limitUpdates", BooleanConfig.LIMIT_UPDATES).register();
+ }
+
private static ArgumentBuilder backendCommand() {
return Commands.literal("backend")
.executes(context -> {
diff --git a/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java b/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java
index a7457e70d..468252db0 100644
--- a/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java
+++ b/src/main/java/com/jozufozu/flywheel/config/FlwConfig.java
@@ -2,6 +2,10 @@ package com.jozufozu.flywheel.config;
import org.apache.commons.lang3.tuple.Pair;
+import com.jozufozu.flywheel.backend.instancing.ratelimit.BandedPrimeLimiter;
+import com.jozufozu.flywheel.backend.instancing.ratelimit.DistanceUpdateLimiter;
+import com.jozufozu.flywheel.backend.instancing.ratelimit.NonLimiter;
+
import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
import net.minecraftforge.fml.ModLoadingContext;
@@ -34,12 +38,25 @@ public class FlwConfig {
return client.debugNormals.get();
}
+ public boolean limitUpdates() {
+ return client.limitUpdates.get();
+ }
+
+ public DistanceUpdateLimiter createUpdateLimiter() {
+ if (limitUpdates()) {
+ return new BandedPrimeLimiter();
+ } else {
+ return new NonLimiter();
+ }
+ }
+
public static void init() {
}
public static class ClientConfig {
public final ForgeConfigSpec.EnumValue engine;
public final BooleanValue debugNormals;
+ public final BooleanValue limitUpdates;
public ClientConfig(ForgeConfigSpec.Builder builder) {
@@ -48,6 +65,9 @@ public class FlwConfig {
debugNormals = builder.comment("Enable or disable a debug overlay that colors pixels by their normal")
.define("debugNormals", false);
+
+ limitUpdates = builder.comment("Enable or disable instance update limiting with distance.")
+ .define("limitUpdates", true);
}
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java
index edfcd2c0c..3d8abed17 100644
--- a/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java
+++ b/src/main/java/com/jozufozu/flywheel/core/crumbling/CrumblingInstanceManager.java
@@ -1,10 +1,9 @@
package com.jozufozu.flywheel.core.crumbling;
import com.jozufozu.flywheel.api.MaterialManager;
+import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
-import net.minecraft.core.BlockPos;
-
public class CrumblingInstanceManager extends BlockEntityInstanceManager {
public CrumblingInstanceManager(MaterialManager materialManager) {
@@ -12,7 +11,7 @@ public class CrumblingInstanceManager extends BlockEntityInstanceManager {
}
@Override
- protected boolean shouldFrameUpdate(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
- return true;
+ protected void updateInstance(DynamicInstance dyn, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
+ dyn.beginFrame();
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
index 64aec0c2a..056966700 100644
--- a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
+++ b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
@@ -21,7 +21,7 @@ public class ForgeEvents {
if (Minecraft.getInstance().options.renderDebug) {
- InstancedRenderDispatcher.getDebugString(event.getLeft());
+ InstancedRenderDispatcher.getDebugString(event.getRight());
}
}