mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 07:26:48 +01:00
Toggleable update limiting
- Extract update limiting behavior to interface - Move original impl to BandedPrimeLimiter - Add dummy NonLimiter impl - Add command/config to toggle update limiting - Refactor InstanceManager to be more consistent between frame updates and tick updates - Bump version - 0.6.1
This commit is contained in:
parent
b403ca3d2b
commit
9219fef20a
13 changed files with 162 additions and 54 deletions
|
@ -2,7 +2,7 @@ org.gradle.jvmargs = -Xmx3G
|
||||||
org.gradle.daemon = false
|
org.gradle.daemon = false
|
||||||
|
|
||||||
# mod version info
|
# mod version info
|
||||||
mod_version = 0.6.0
|
mod_version = 0.6.1
|
||||||
mc_update_version = 1.18
|
mc_update_version = 1.18
|
||||||
minecraft_version = 1.18.1
|
minecraft_version = 1.18.1
|
||||||
forge_version = 39.0.59
|
forge_version = 39.0.59
|
||||||
|
|
|
@ -14,13 +14,14 @@ import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
import com.jozufozu.flywheel.backend.instancing.instancing.InstancingEngine;
|
||||||
|
import com.jozufozu.flywheel.backend.instancing.ratelimit.DistanceUpdateLimiter;
|
||||||
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.light.LightUpdater;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.util.Mth;
|
|
||||||
|
|
||||||
public abstract class InstanceManager<T> implements InstancingEngine.OriginShiftListener {
|
public abstract class InstanceManager<T> implements InstancingEngine.OriginShiftListener {
|
||||||
|
|
||||||
|
@ -33,8 +34,8 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
protected final Object2ObjectOpenHashMap<T, TickableInstance> tickableInstances;
|
protected final Object2ObjectOpenHashMap<T, TickableInstance> tickableInstances;
|
||||||
protected final Object2ObjectOpenHashMap<T, DynamicInstance> dynamicInstances;
|
protected final Object2ObjectOpenHashMap<T, DynamicInstance> dynamicInstances;
|
||||||
|
|
||||||
protected int frame;
|
protected DistanceUpdateLimiter frame;
|
||||||
protected int tick;
|
protected DistanceUpdateLimiter tick;
|
||||||
|
|
||||||
public InstanceManager(MaterialManager materialManager) {
|
public InstanceManager(MaterialManager materialManager) {
|
||||||
this.materialManager = materialManager;
|
this.materialManager = materialManager;
|
||||||
|
@ -44,6 +45,10 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
|
|
||||||
this.dynamicInstances = new Object2ObjectOpenHashMap<>();
|
this.dynamicInstances = new Object2ObjectOpenHashMap<>();
|
||||||
this.tickableInstances = new Object2ObjectOpenHashMap<>();
|
this.tickableInstances = new Object2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
|
FlwConfig config = FlwConfig.get();
|
||||||
|
frame = config.createUpdateLimiter();
|
||||||
|
tick = config.createUpdateLimiter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -86,7 +91,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public void tick(TaskEngine taskEngine, double cameraX, double cameraY, double cameraZ) {
|
public void tick(TaskEngine taskEngine, double cameraX, double cameraY, double cameraZ) {
|
||||||
tick++;
|
tick.tick();
|
||||||
processQueuedUpdates();
|
processQueuedUpdates();
|
||||||
|
|
||||||
// integer camera pos as a micro-optimization
|
// integer camera pos as a micro-optimization
|
||||||
|
@ -112,7 +117,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickInstance(int cX, int cY, int cZ, TickableInstance instance) {
|
protected void tickInstance(int cX, int cY, int cZ, TickableInstance instance) {
|
||||||
if (!instance.decreaseTickRateWithDistance()) {
|
if (!instance.decreaseTickRateWithDistance()) {
|
||||||
instance.tick();
|
instance.tick();
|
||||||
return;
|
return;
|
||||||
|
@ -124,11 +129,11 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
int dY = pos.getY() - cY;
|
int dY = pos.getY() - cY;
|
||||||
int dZ = pos.getZ() - cZ;
|
int dZ = pos.getZ() - cZ;
|
||||||
|
|
||||||
if ((tick % getUpdateDivisor(dX, dY, dZ)) == 0) instance.tick();
|
if (tick.shouldUpdate(dX, dY, dZ)) instance.tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void beginFrame(TaskEngine taskEngine, Camera info) {
|
public void beginFrame(TaskEngine taskEngine, Camera info) {
|
||||||
frame++;
|
frame.tick();
|
||||||
processQueuedAdditions();
|
processQueuedAdditions();
|
||||||
|
|
||||||
Vector3f look = info.getLookVector();
|
Vector3f look = info.getLookVector();
|
||||||
|
@ -151,8 +156,7 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
List<DynamicInstance> sub = instances.subList(start, end);
|
List<DynamicInstance> sub = instances.subList(start, end);
|
||||||
taskEngine.submit(() -> {
|
taskEngine.submit(() -> {
|
||||||
for (DynamicInstance dyn : sub) {
|
for (DynamicInstance dyn : sub) {
|
||||||
if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
updateInstance(dyn, lookX, lookY, lookZ, cX, cY, cZ);
|
||||||
dyn.beginFrame();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -160,6 +164,28 @@ public abstract class InstanceManager<T> implements InstancingEngine.OriginShift
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void updateInstance(DynamicInstance dyn, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
||||||
|
if (!dyn.decreaseFramerateWithDistance()) {
|
||||||
|
dyn.beginFrame();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPos worldPos = dyn.getWorldPosition();
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (frame.shouldUpdate(dX, dY, dZ))
|
||||||
|
dyn.beginFrame();
|
||||||
|
}
|
||||||
|
|
||||||
public void add(T obj) {
|
public void add(T obj) {
|
||||||
if (!Backend.isOn()) return;
|
if (!Backend.isOn()) return;
|
||||||
|
|
||||||
|
@ -268,29 +294,6 @@ public abstract class InstanceManager<T> 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) {
|
protected void addInternal(T obj) {
|
||||||
if (!Backend.isOn()) return;
|
if (!Backend.isOn()) return;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
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.BeginFrameEvent;
|
||||||
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
|
||||||
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
import com.jozufozu.flywheel.event.RenderLayerEvent;
|
||||||
|
@ -123,6 +125,7 @@ public class InstancedRenderDispatcher {
|
||||||
if (Backend.isOn()) {
|
if (Backend.isOn()) {
|
||||||
InstanceWorld instanceWorld = instanceWorlds.get(Minecraft.getInstance().level);
|
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());
|
debug.add("B: " + instanceWorld.blockEntityInstanceManager.getObjectCount() + ", E: " + instanceWorld.entityInstanceManager.getObjectCount());
|
||||||
instanceWorld.engine.addDebugInfo(debug);
|
instanceWorld.engine.addDebugInfo(debug);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -154,9 +154,9 @@ public class InstancingEngine<P extends WorldProgram> implements Engine {
|
||||||
@Override
|
@Override
|
||||||
public void addDebugInfo(List<String> info) {
|
public void addDebugInfo(List<String> info) {
|
||||||
info.add("GL33 Instanced Arrays");
|
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("Instances: " + getGroupsToRender(null).mapToInt(InstancedMaterialGroup::getInstanceCount).sum());
|
||||||
info.add("Vertices: " + getGroupsToRender(null).mapToInt(InstancedMaterialGroup::getVertexCount).sum());
|
info.add("Vertices: " + getGroupsToRender(null).mapToInt(InstancedMaterialGroup::getVertexCount).sum());
|
||||||
|
info.add("Origin: " + originCoordinate.getX() + ", " + originCoordinate.getY() + ", " + originCoordinate.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
@FunctionalInterface
|
||||||
|
|
|
@ -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)];
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,8 @@
|
||||||
package com.jozufozu.flywheel.config;
|
package com.jozufozu.flywheel.config;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
|
||||||
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
|
|
||||||
import net.minecraft.ChatFormatting;
|
import net.minecraft.ChatFormatting;
|
||||||
import net.minecraft.client.Minecraft;
|
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.Component;
|
||||||
import net.minecraft.network.chat.MutableComponent;
|
import net.minecraft.network.chat.MutableComponent;
|
||||||
import net.minecraft.network.chat.TextComponent;
|
import net.minecraft.network.chat.TextComponent;
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
||||||
|
|
||||||
public enum BooleanConfig {
|
public enum BooleanConfig {
|
||||||
NORMAL_OVERLAY(() -> BooleanConfig::normalOverlay),
|
NORMAL_OVERLAY(BooleanConfig::normalOverlay),
|
||||||
;
|
LIMIT_UPDATES(BooleanConfig::limitUpdates);
|
||||||
|
|
||||||
final Supplier<Consumer<BooleanDirective>> receiver;
|
final Consumer<BooleanDirective> receiver;
|
||||||
|
|
||||||
BooleanConfig(Supplier<Consumer<BooleanDirective>> receiver) {
|
BooleanConfig(Consumer<BooleanDirective> receiver) {
|
||||||
this.receiver = 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) {
|
private static void normalOverlay(BooleanDirective state) {
|
||||||
LocalPlayer player = Minecraft.getInstance().player;
|
LocalPlayer player = Minecraft.getInstance().player;
|
||||||
if (player == null || state == null) return;
|
if (player == null || state == null) return;
|
||||||
|
@ -40,7 +57,7 @@ public enum BooleanConfig {
|
||||||
player.displayClientMessage(text, false);
|
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);
|
return b ? new TextComponent("enabled").withStyle(ChatFormatting.DARK_GREEN) : new TextComponent("disabled").withStyle(ChatFormatting.RED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,17 +20,17 @@ public class BooleanConfigCommand {
|
||||||
public ArgumentBuilder<CommandSourceStack, ?> register() {
|
public ArgumentBuilder<CommandSourceStack, ?> register() {
|
||||||
return Commands.literal(name)
|
return Commands.literal(name)
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
value.receiver.get().accept(BooleanDirective.DISPLAY);
|
value.receiver.accept(BooleanDirective.DISPLAY);
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
})
|
})
|
||||||
.then(Commands.literal("on")
|
.then(Commands.literal("on")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
value.receiver.get().accept(BooleanDirective.TRUE);
|
value.receiver.accept(BooleanDirective.TRUE);
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}))
|
}))
|
||||||
.then(Commands.literal("off")
|
.then(Commands.literal("off")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
value.receiver.get().accept(BooleanDirective.FALSE);
|
value.receiver.accept(BooleanDirective.FALSE);
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,15 +13,20 @@ public class FlwCommands {
|
||||||
CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher();
|
CommandDispatcher<CommandSourceStack> dispatcher = event.getDispatcher();
|
||||||
|
|
||||||
dispatcher.register(Commands.literal("flywheel")
|
dispatcher.register(Commands.literal("flywheel")
|
||||||
.then(debugCommand())
|
.then(debugNormalsCommand())
|
||||||
.then(backendCommand())
|
.then(backendCommand())
|
||||||
|
.then(limitUpdatesCommand())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ArgumentBuilder<CommandSourceStack, ?> debugCommand() {
|
private static ArgumentBuilder<CommandSourceStack, ?> debugNormalsCommand() {
|
||||||
return new BooleanConfigCommand("debugNormals", BooleanConfig.NORMAL_OVERLAY).register();
|
return new BooleanConfigCommand("debugNormals", BooleanConfig.NORMAL_OVERLAY).register();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static ArgumentBuilder<CommandSourceStack, ?> limitUpdatesCommand() {
|
||||||
|
return new BooleanConfigCommand("limitUpdates", BooleanConfig.LIMIT_UPDATES).register();
|
||||||
|
}
|
||||||
|
|
||||||
private static ArgumentBuilder<CommandSourceStack, ?> backendCommand() {
|
private static ArgumentBuilder<CommandSourceStack, ?> backendCommand() {
|
||||||
return Commands.literal("backend")
|
return Commands.literal("backend")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
|
|
|
@ -2,6 +2,10 @@ package com.jozufozu.flywheel.config;
|
||||||
|
|
||||||
import org.apache.commons.lang3.tuple.Pair;
|
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;
|
||||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
import net.minecraftforge.fml.ModLoadingContext;
|
||||||
|
@ -34,12 +38,25 @@ public class FlwConfig {
|
||||||
return client.debugNormals.get();
|
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 void init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ClientConfig {
|
public static class ClientConfig {
|
||||||
public final ForgeConfigSpec.EnumValue<FlwEngine> engine;
|
public final ForgeConfigSpec.EnumValue<FlwEngine> engine;
|
||||||
public final BooleanValue debugNormals;
|
public final BooleanValue debugNormals;
|
||||||
|
public final BooleanValue limitUpdates;
|
||||||
|
|
||||||
public ClientConfig(ForgeConfigSpec.Builder builder) {
|
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")
|
debugNormals = builder.comment("Enable or disable a debug overlay that colors pixels by their normal")
|
||||||
.define("debugNormals", false);
|
.define("debugNormals", false);
|
||||||
|
|
||||||
|
limitUpdates = builder.comment("Enable or disable instance update limiting with distance.")
|
||||||
|
.define("limitUpdates", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package com.jozufozu.flywheel.core.crumbling;
|
package com.jozufozu.flywheel.core.crumbling;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.MaterialManager;
|
import com.jozufozu.flywheel.api.MaterialManager;
|
||||||
|
import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
|
|
||||||
public class CrumblingInstanceManager extends BlockEntityInstanceManager {
|
public class CrumblingInstanceManager extends BlockEntityInstanceManager {
|
||||||
|
|
||||||
public CrumblingInstanceManager(MaterialManager materialManager) {
|
public CrumblingInstanceManager(MaterialManager materialManager) {
|
||||||
|
@ -12,7 +11,7 @@ public class CrumblingInstanceManager extends BlockEntityInstanceManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean shouldFrameUpdate(BlockPos worldPos, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
protected void updateInstance(DynamicInstance dyn, float lookX, float lookY, float lookZ, int cX, int cY, int cZ) {
|
||||||
return true;
|
dyn.beginFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class ForgeEvents {
|
||||||
|
|
||||||
if (Minecraft.getInstance().options.renderDebug) {
|
if (Minecraft.getInstance().options.renderDebug) {
|
||||||
|
|
||||||
InstancedRenderDispatcher.getDebugString(event.getLeft());
|
InstancedRenderDispatcher.getDebugString(event.getRight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue