diff --git a/src/main/java/me/cortex/voxy/client/VoxyClient.java b/src/main/java/me/cortex/voxy/client/VoxyClient.java index 2369e208..a14d4e95 100644 --- a/src/main/java/me/cortex/voxy/client/VoxyClient.java +++ b/src/main/java/me/cortex/voxy/client/VoxyClient.java @@ -1,19 +1,14 @@ package me.cortex.voxy.client; -import me.cortex.voxy.client.core.VoxelCore; -import me.cortex.voxy.client.saver.ContextSelectionSystem; -import me.cortex.voxy.client.terrain.WorldImportCommand; import me.cortex.voxy.commonImpl.VoxyCommon; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.command.v2.ClientCommandRegistrationCallback; -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientWorldEvents; -import net.minecraft.client.world.ClientWorld; public class VoxyClient implements ClientModInitializer { @Override public void onInitializeClient() { ClientCommandRegistrationCallback.EVENT.register((dispatcher, registryAccess) -> { - dispatcher.register(WorldImportCommand.register()); + dispatcher.register(VoxyCommands.register()); }); VoxyCommon.setInstanceFactory(VoxyClientInstance::new); } diff --git a/src/main/java/me/cortex/voxy/client/VoxyClientInstance.java b/src/main/java/me/cortex/voxy/client/VoxyClientInstance.java index 70da12a9..55867881 100644 --- a/src/main/java/me/cortex/voxy/client/VoxyClientInstance.java +++ b/src/main/java/me/cortex/voxy/client/VoxyClientInstance.java @@ -1,19 +1,13 @@ package me.cortex.voxy.client; import me.cortex.voxy.client.config.VoxyConfig; -import me.cortex.voxy.client.core.WorldImportWrapper; import me.cortex.voxy.client.saver.ContextSelectionSystem; -import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.world.WorldEngine; -import me.cortex.voxy.commonImpl.IVoxyWorldGetter; -import me.cortex.voxy.commonImpl.IVoxyWorldSetter; +import me.cortex.voxy.commonImpl.IVoxyWorld; import me.cortex.voxy.commonImpl.ImportManager; import me.cortex.voxy.commonImpl.VoxyInstance; -import me.cortex.voxy.commonImpl.importers.DHImporter; import net.minecraft.client.world.ClientWorld; -import java.io.File; - public class VoxyClientInstance extends VoxyInstance { private static final ContextSelectionSystem SELECTOR = new ContextSelectionSystem(); @@ -27,10 +21,10 @@ public class VoxyClientInstance extends VoxyInstance { } public WorldEngine getOrMakeRenderWorld(ClientWorld world) { - var vworld = ((IVoxyWorldGetter)world).getWorldEngine(); + var vworld = ((IVoxyWorld)world).getWorldEngine(); if (vworld == null) { vworld = this.createWorld(SELECTOR.getBestSelectionOrCreate(world).createSectionStorageBackend()); - ((IVoxyWorldSetter)world).setWorldEngine(vworld); + ((IVoxyWorld)world).setWorldEngine(vworld); } else { if (!this.activeWorlds.contains(vworld)) { throw new IllegalStateException("World referenced does not exist in instance"); diff --git a/src/main/java/me/cortex/voxy/client/terrain/WorldImportCommand.java b/src/main/java/me/cortex/voxy/client/VoxyCommands.java similarity index 81% rename from src/main/java/me/cortex/voxy/client/terrain/WorldImportCommand.java rename to src/main/java/me/cortex/voxy/client/VoxyCommands.java index b38e7391..9366d6aa 100644 --- a/src/main/java/me/cortex/voxy/client/terrain/WorldImportCommand.java +++ b/src/main/java/me/cortex/voxy/client/VoxyCommands.java @@ -1,13 +1,13 @@ -package me.cortex.voxy.client.terrain; +package me.cortex.voxy.client; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; -import me.cortex.voxy.client.VoxyClientInstance; +import me.cortex.voxy.client.core.IGetVoxyRenderSystem; +import me.cortex.voxy.commonImpl.IVoxyWorld; import me.cortex.voxy.commonImpl.VoxyCommon; -import me.cortex.voxy.commonImpl.VoxyInstance; import me.cortex.voxy.commonImpl.importers.DHImporter; import me.cortex.voxy.commonImpl.importers.WorldImporter; import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager; @@ -22,35 +22,64 @@ import java.nio.file.Path; import java.util.concurrent.CompletableFuture; -public class WorldImportCommand { +public class VoxyCommands { public static LiteralArgumentBuilder register() { return ClientCommandManager.literal("voxy").requires((ctx)-> VoxyCommon.getInstance() != null) + .then(ClientCommandManager.literal("reload") + .executes(VoxyCommands::reloadInstance)) .then(ClientCommandManager.literal("import") .then(ClientCommandManager.literal("world") .then(ClientCommandManager.argument("world_name", StringArgumentType.string()) - .suggests(WorldImportCommand::importWorldSuggester) - .executes(WorldImportCommand::importWorld))) + .suggests(VoxyCommands::importWorldSuggester) + .executes(VoxyCommands::importWorld))) .then(ClientCommandManager.literal("bobby") .then(ClientCommandManager.argument("world_name", StringArgumentType.string()) - .suggests(WorldImportCommand::importBobbySuggester) - .executes(WorldImportCommand::importBobby))) + .suggests(VoxyCommands::importBobbySuggester) + .executes(VoxyCommands::importBobby))) .then(ClientCommandManager.literal("raw") .then(ClientCommandManager.argument("path", StringArgumentType.string()) - .executes(WorldImportCommand::importRaw))) + .executes(VoxyCommands::importRaw))) .then(ClientCommandManager.literal("zip") .then(ClientCommandManager.argument("zipPath", StringArgumentType.string()) - .executes(WorldImportCommand::importZip) + .executes(VoxyCommands::importZip) .then(ClientCommandManager.argument("innerPath", StringArgumentType.string()) - .executes(WorldImportCommand::importZip)))) + .executes(VoxyCommands::importZip)))) .then(ClientCommandManager.literal("distant_horizons") .then(ClientCommandManager.argument("sqlDbPath", StringArgumentType.string()) - .executes(WorldImportCommand::importDistantHorizons))) + .executes(VoxyCommands::importDistantHorizons))) .then(ClientCommandManager.literal("cancel") - .executes(WorldImportCommand::cancelImport)) + .executes(VoxyCommands::cancelImport)) ); } + private static int reloadInstance(CommandContext ctx) { + var instance = (VoxyClientInstance)VoxyCommon.getInstance(); + if (instance == null) { + return 1; + } + var wr = MinecraftClient.getInstance().worldRenderer; + if (wr!=null) { + ((IGetVoxyRenderSystem)wr).shutdownRenderer(); + } + var w = ((IVoxyWorld)MinecraftClient.getInstance().world); + if (w != null) { + if (w.getWorldEngine() != null) { + instance.stopWorld(w.getWorldEngine()); + } + w.setWorldEngine(null); + } + VoxyCommon.shutdownInstance(); + VoxyCommon.createInstance(); + if (wr!=null) { + ((IGetVoxyRenderSystem)wr).createRenderer(); + } + return 0; + } + + + + private static int importDistantHorizons(CommandContext ctx) { var instance = (VoxyClientInstance)VoxyCommon.getInstance(); if (instance == null) { diff --git a/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenFactory.java b/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenFactory.java index 9da13bf9..8607f588 100644 --- a/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenFactory.java +++ b/src/main/java/me/cortex/voxy/client/config/VoxyConfigScreenFactory.java @@ -3,8 +3,7 @@ package me.cortex.voxy.client.config; import com.terraformersmc.modmenu.api.ConfigScreenFactory; import com.terraformersmc.modmenu.api.ModMenuApi; import me.cortex.voxy.client.core.IGetVoxyRenderSystem; -import me.cortex.voxy.commonImpl.IVoxyWorldGetter; -import me.cortex.voxy.commonImpl.IVoxyWorldSetter; +import me.cortex.voxy.commonImpl.IVoxyWorld; import me.cortex.voxy.commonImpl.VoxyCommon; import me.shedaniel.clothconfig2.api.ConfigBuilder; import me.shedaniel.clothconfig2.api.ConfigCategory; @@ -40,7 +39,7 @@ public class VoxyConfigScreenFactory implements ModMenuApi { builder.setSavingRunnable(() -> { //After saving the core should be reloaded/reset var worldRenderer = MinecraftClient.getInstance().worldRenderer; - var world = MinecraftClient.getInstance().world; + var world = ((IVoxyWorld) MinecraftClient.getInstance().world); if (worldRenderer != null && (ON_SAVE_RELOAD_ALL||ON_SAVE_RELOAD_RENDERER)) { //Shudown renderer ((IGetVoxyRenderSystem) worldRenderer).shutdownRenderer(); @@ -49,11 +48,11 @@ public class VoxyConfigScreenFactory implements ModMenuApi { if (world != null && ON_SAVE_RELOAD_ALL) { //This is a hack inserted for the client world thing //TODO: FIXME: MAKE BETTER - var engine = ((IVoxyWorldGetter) world).getWorldEngine(); + var engine = world.getWorldEngine(); if (engine != null) { VoxyCommon.getInstance().stopWorld(engine); } - ((IVoxyWorldSetter) world).setWorldEngine(null); + world.setWorldEngine(null); } //Shutdown instance if (ON_SAVE_RELOAD_ALL) { diff --git a/src/main/java/me/cortex/voxy/client/core/rendering/building/RenderDataFactory45.java b/src/main/java/me/cortex/voxy/client/core/rendering/building/RenderDataFactory45.java index aeac2cb8..05705867 100644 --- a/src/main/java/me/cortex/voxy/client/core/rendering/building/RenderDataFactory45.java +++ b/src/main/java/me/cortex/voxy/client/core/rendering/building/RenderDataFactory45.java @@ -421,7 +421,11 @@ public class RenderDataFactory45 { //TODO: swap this out for something not getting the next entry long A = this.sectionData[idx * 2]; - + long B = this.sectionData[idx * 2+1]; + if (ModelQueries.isFluid(B)) { + this.blockMesher.putNext(0); + continue; + } //Example thing thats just wrong but as example this.blockMesher.putNext((long) (false ? 0L : 1L) | ((A & 0xFFFFL) << 26) | diff --git a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinClientLoginNetworkHandler.java b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinClientLoginNetworkHandler.java new file mode 100644 index 00000000..0eb86ace --- /dev/null +++ b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinClientLoginNetworkHandler.java @@ -0,0 +1,28 @@ +package me.cortex.voxy.client.mixin.minecraft; + +import me.cortex.voxy.client.LoadException; +import me.cortex.voxy.client.config.VoxyConfig; +import me.cortex.voxy.commonImpl.VoxyCommon; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.gui.screen.Screen; +import net.minecraft.client.network.*; +import net.minecraft.network.ClientConnection; +import net.minecraft.network.packet.Packet; +import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.time.Duration; +import java.util.function.Consumer; + +@Mixin(ClientLoginNetworkHandler.class) +public class MixinClientLoginNetworkHandler { + @Inject(method = "", at = @At(value = "TAIL")) + private void voxy$init(ClientConnection connection, MinecraftClient client, ServerInfo serverInfo, Screen parentScreen, boolean newWorld, Duration worldLoadTime, Consumer statusConsumer, CookieStorage cookieStorage, CallbackInfo ci) { + if (VoxyConfig.CONFIG.enabled) { + VoxyCommon.createInstance(); + } + } +} diff --git a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinClientPlayNetworkHandler.java b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinClientPlayNetworkHandler.java deleted file mode 100644 index 3c9d2e60..00000000 --- a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinClientPlayNetworkHandler.java +++ /dev/null @@ -1,23 +0,0 @@ -package me.cortex.voxy.client.mixin.minecraft; - -import me.cortex.voxy.client.LoadException; -import me.cortex.voxy.client.config.VoxyConfig; -import me.cortex.voxy.commonImpl.VoxyCommon; -import net.minecraft.client.network.ClientCommonNetworkHandler; -import net.minecraft.client.network.ClientPlayNetworkHandler; -import net.minecraft.network.packet.Packet; -import net.minecraft.network.packet.s2c.play.GameJoinS2CPacket; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(ClientPlayNetworkHandler.class) -public class MixinClientPlayNetworkHandler { - @Inject(method = "onGameJoin", at = @At(value = "NEW", target = "(Lnet/minecraft/client/network/ClientPlayNetworkHandler;Lnet/minecraft/client/world/ClientWorld$Properties;Lnet/minecraft/registry/RegistryKey;Lnet/minecraft/registry/entry/RegistryEntry;IILnet/minecraft/client/render/WorldRenderer;ZJI)Lnet/minecraft/client/world/ClientWorld;", shift = At.Shift.BEFORE)) - private void voxy$init(GameJoinS2CPacket packet, CallbackInfo ci) { - if (VoxyConfig.CONFIG.enabled) { - VoxyCommon.createInstance(); - } - } -} diff --git a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinWorldRenderer.java b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinWorldRenderer.java index 763485b6..f8552101 100644 --- a/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinWorldRenderer.java +++ b/src/main/java/me/cortex/voxy/client/mixin/minecraft/MixinWorldRenderer.java @@ -6,10 +6,8 @@ import me.cortex.voxy.client.core.IGetVoxyRenderSystem; import me.cortex.voxy.client.core.rendering.VoxyRenderSystem; import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.world.WorldEngine; -import me.cortex.voxy.commonImpl.IVoxyWorldGetter; -import me.cortex.voxy.commonImpl.IVoxyWorldSetter; +import me.cortex.voxy.commonImpl.IVoxyWorld; import me.cortex.voxy.commonImpl.VoxyCommon; -import me.cortex.voxy.commonImpl.VoxyInstance; import net.minecraft.client.render.*; import net.minecraft.client.util.ObjectAllocator; import net.minecraft.client.world.ClientWorld; @@ -54,11 +52,11 @@ public abstract class MixinWorldRenderer implements IGetVoxyRenderSystem { this.shutdownRenderer(); if (this.world != null) { - var engine = ((IVoxyWorldGetter)this.world).getWorldEngine(); + var engine = ((IVoxyWorld)this.world).getWorldEngine(); if (engine != null) { VoxyCommon.getInstance().stopWorld(engine); } - ((IVoxyWorldSetter)this.world).setWorldEngine(null); + ((IVoxyWorld)this.world).setWorldEngine(null); } } } diff --git a/src/main/java/me/cortex/voxy/common/world/WorldEngine.java b/src/main/java/me/cortex/voxy/common/world/WorldEngine.java index 011fded2..b6e1fd53 100644 --- a/src/main/java/me/cortex/voxy/common/world/WorldEngine.java +++ b/src/main/java/me/cortex/voxy/common/world/WorldEngine.java @@ -202,6 +202,11 @@ public class WorldEngine { public void free() { + //Cannot free while there are loaded sections + if (this.sectionTracker.getLoadedCacheCount() != 0) { + throw new IllegalStateException(); + } + this.thisTracker.free(); this.isLive = false; try {this.mapper.close();} catch (Exception e) {Logger.error(e);} diff --git a/src/main/java/me/cortex/voxy/common/world/service/VoxelIngestService.java b/src/main/java/me/cortex/voxy/common/world/service/VoxelIngestService.java index ce24b8b1..83b715e2 100644 --- a/src/main/java/me/cortex/voxy/common/world/service/VoxelIngestService.java +++ b/src/main/java/me/cortex/voxy/common/world/service/VoxelIngestService.java @@ -1,6 +1,5 @@ package me.cortex.voxy.common.world.service; -import it.unimi.dsi.fastutil.Pair; import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.voxelization.ILightingSupplier; import me.cortex.voxy.common.voxelization.VoxelizedSection; @@ -8,15 +7,13 @@ import me.cortex.voxy.common.voxelization.WorldConversionFactory; import me.cortex.voxy.common.world.WorldEngine; import me.cortex.voxy.common.thread.ServiceSlice; import me.cortex.voxy.common.thread.ServiceThreadPool; -import me.cortex.voxy.commonImpl.IVoxyWorldGetter; +import me.cortex.voxy.commonImpl.IVoxyWorld; import net.minecraft.util.math.ChunkSectionPos; import net.minecraft.world.LightType; import net.minecraft.world.chunk.ChunkNibbleArray; import net.minecraft.world.chunk.ChunkSection; import net.minecraft.world.chunk.WorldChunk; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedDeque; public class VoxelIngestService { @@ -80,7 +77,7 @@ public class VoxelIngestService { } public void enqueueIngest(WorldChunk chunk, boolean ignoreOnNullWorld) { - var engine = ((IVoxyWorldGetter)chunk.getWorld()).getWorldEngine(); + var engine = ((IVoxyWorld)chunk.getWorld()).getWorldEngine(); if (engine == null) { if (!ignoreOnNullWorld) { Logger.error("Could not ingest chunk as does not have world engine"); diff --git a/src/main/java/me/cortex/voxy/commonImpl/IVoxyWorldSetter.java b/src/main/java/me/cortex/voxy/commonImpl/IVoxyWorld.java similarity index 67% rename from src/main/java/me/cortex/voxy/commonImpl/IVoxyWorldSetter.java rename to src/main/java/me/cortex/voxy/commonImpl/IVoxyWorld.java index 5b38b8af..b6ce3512 100644 --- a/src/main/java/me/cortex/voxy/commonImpl/IVoxyWorldSetter.java +++ b/src/main/java/me/cortex/voxy/commonImpl/IVoxyWorld.java @@ -2,6 +2,7 @@ package me.cortex.voxy.commonImpl; import me.cortex.voxy.common.world.WorldEngine; -public interface IVoxyWorldSetter { +public interface IVoxyWorld { + WorldEngine getWorldEngine(); void setWorldEngine(WorldEngine engine); } diff --git a/src/main/java/me/cortex/voxy/commonImpl/IVoxyWorldGetter.java b/src/main/java/me/cortex/voxy/commonImpl/IVoxyWorldGetter.java deleted file mode 100644 index ad5f8459..00000000 --- a/src/main/java/me/cortex/voxy/commonImpl/IVoxyWorldGetter.java +++ /dev/null @@ -1,7 +0,0 @@ -package me.cortex.voxy.commonImpl; - -import me.cortex.voxy.common.world.WorldEngine; - -public interface IVoxyWorldGetter { - WorldEngine getWorldEngine(); -} diff --git a/src/main/java/me/cortex/voxy/commonImpl/VoxyCommon.java b/src/main/java/me/cortex/voxy/commonImpl/VoxyCommon.java index 4579b209..be65a65d 100644 --- a/src/main/java/me/cortex/voxy/commonImpl/VoxyCommon.java +++ b/src/main/java/me/cortex/voxy/commonImpl/VoxyCommon.java @@ -30,7 +30,7 @@ public class VoxyCommon implements ModInitializer { } //This is hardcoded like this because people do not understand what they are doing - private static final boolean GlobalVerificationDisableOverride = false;//System.getProperty("voxy.verificationDisableOverride", "false").equals("true"); + private static final boolean GlobalVerificationDisableOverride = true;//System.getProperty("voxy.verificationDisableOverride", "false").equals("true"); public static boolean isVerificationFlagOn(String name) { return (!GlobalVerificationDisableOverride) && System.getProperty("voxy."+name, "true").equals("true"); } diff --git a/src/main/java/me/cortex/voxy/commonImpl/VoxyInstance.java b/src/main/java/me/cortex/voxy/commonImpl/VoxyInstance.java index f58abf60..63a792fe 100644 --- a/src/main/java/me/cortex/voxy/commonImpl/VoxyInstance.java +++ b/src/main/java/me/cortex/voxy/commonImpl/VoxyInstance.java @@ -128,6 +128,18 @@ public class VoxyInstance { this.importManager.cancelImport(world); + if (world.getActiveSectionCount() != 0) { + Logger.warn("Waiting for world to finish use"); + while (world.getActiveSectionCount() != 0) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + } + + //TODO: maybe replace the flush with an atomic "in queue" counter that is per world this.flush(); world.free(); diff --git a/src/main/java/me/cortex/voxy/commonImpl/mixin/minecraft/MixinWorld.java b/src/main/java/me/cortex/voxy/commonImpl/mixin/minecraft/MixinWorld.java index d6a8a966..65d0bd90 100644 --- a/src/main/java/me/cortex/voxy/commonImpl/mixin/minecraft/MixinWorld.java +++ b/src/main/java/me/cortex/voxy/commonImpl/mixin/minecraft/MixinWorld.java @@ -1,23 +1,16 @@ package me.cortex.voxy.commonImpl.mixin.minecraft; -import me.cortex.voxy.common.Logger; import me.cortex.voxy.common.world.WorldEngine; -import me.cortex.voxy.commonImpl.IVoxyWorldGetter; -import me.cortex.voxy.commonImpl.IVoxyWorldSetter; -import me.cortex.voxy.commonImpl.VoxyCommon; +import me.cortex.voxy.commonImpl.IVoxyWorld; import net.minecraft.world.World; import net.minecraft.world.block.NeighborUpdater; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(World.class) -public class MixinWorld implements IVoxyWorldGetter, IVoxyWorldSetter { - @Shadow @Final protected NeighborUpdater neighborUpdater; +public class MixinWorld implements IVoxyWorld { @Unique private WorldEngine voxyWorld; @Override diff --git a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl index 8ccddd36..af14d93d 100644 --- a/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl +++ b/src/main/resources/assets/voxy/shaders/lod/hierarchical/screenspace.glsl @@ -54,8 +54,8 @@ void setupScreenspace(in UnpackedNode node) { //NOTE!: cant this be precomputed and put in an array?? in the scene uniform?? vec4 pPoint = (VP*vec4(vec3((i&1)!=0,(i&2)!=0,(i&4)!=0)*(32<