diff --git a/common/src/main/java/org/vivecraft/client/Xplat.java b/common/src/main/java/org/vivecraft/client/Xplat.java index 8c2b0b77e..bc812b72a 100644 --- a/common/src/main/java/org/vivecraft/client/Xplat.java +++ b/common/src/main/java/org/vivecraft/client/Xplat.java @@ -27,6 +27,18 @@ public interface Xplat { * You should also get the IntelliJ plugin to help with @ExpectPlatform. */ + enum ModLoader{ + FABRIC("fabric"), + FORGE("forge"), + NEOFORGE("neoforge"); + + public final String name; + + ModLoader(String name) { + this.name = name; + } + } + @ExpectPlatform static boolean isModLoaded(String name) { return false; @@ -43,8 +55,8 @@ static boolean isDedicatedServer() { } @ExpectPlatform - static String getModloader() { - return ""; + static ModLoader getModloader() { + throw new AssertionError(); } @ExpectPlatform diff --git a/common/src/main/java/org/vivecraft/client/gui/settings/GuiRoomscaleSettings.java b/common/src/main/java/org/vivecraft/client/gui/settings/GuiRoomscaleSettings.java index b9642327e..7f94d5f11 100644 --- a/common/src/main/java/org/vivecraft/client/gui/settings/GuiRoomscaleSettings.java +++ b/common/src/main/java/org/vivecraft/client/gui/settings/GuiRoomscaleSettings.java @@ -15,7 +15,9 @@ public class GuiRoomscaleSettings extends GuiVROptionsBase { VRSettings.VrOptions.BOW_MODE, VRSettings.VrOptions.BACKPACK_SWITCH, VRSettings.VrOptions.ALLOW_CRAWLING, - VRSettings.VrOptions.REALISTIC_DISMOUNT + VRSettings.VrOptions.REALISTIC_DISMOUNT, + VRSettings.VrOptions.REALISTIC_BLOCK_INTERACT, + VRSettings.VrOptions.REALISTIC_ENTITY_INTERACT }; public GuiRoomscaleSettings(Screen guiScreen) { diff --git a/common/src/main/java/org/vivecraft/client/gui/settings/GuiSeatedOptions.java b/common/src/main/java/org/vivecraft/client/gui/settings/GuiSeatedOptions.java index cd1fcc38c..822afbf01 100644 --- a/common/src/main/java/org/vivecraft/client/gui/settings/GuiSeatedOptions.java +++ b/common/src/main/java/org/vivecraft/client/gui/settings/GuiSeatedOptions.java @@ -14,7 +14,7 @@ public class GuiSeatedOptions extends GuiVROptionsBase { new VROptionEntry(VRSettings.VrOptions.WALK_UP_BLOCKS), new VROptionEntry(VRSettings.VrOptions.WORLD_ROTATION_INCREMENT), new VROptionEntry(VRSettings.VrOptions.VEHICLE_ROTATION), - new VROptionEntry(VRSettings.VrOptions.DUMMY), + new VROptionEntry(VRSettings.VrOptions.REVERSE_HANDS), new VROptionEntry(VRSettings.VrOptions.SEATED_FREE_MOVE, true), new VROptionEntry(VRSettings.VrOptions.RIGHT_CLICK_DELAY, false), new VROptionEntry("vivecraft.options.screen.teleport.button", (button, mousePos) -> { diff --git a/common/src/main/java/org/vivecraft/client/render/HMDLayer.java b/common/src/main/java/org/vivecraft/client/render/HMDLayer.java index bcd7bc515..53c47515c 100644 --- a/common/src/main/java/org/vivecraft/client/render/HMDLayer.java +++ b/common/src/main/java/org/vivecraft/client/render/HMDLayer.java @@ -24,7 +24,7 @@ public HMDLayer(RenderLayerParent vrPlayerModel) { + if (this.getParentModel().head.visible && this.getParentModel() instanceof VRPlayerModel vrPlayerModel) { VRPlayersClient.RotInfo rotinfo = VRPlayersClient.getInstance().getRotationsForPlayer(entity.getUUID()); ResourceLocation hmd; switch (rotinfo.hmd) { diff --git a/common/src/main/java/org/vivecraft/client/render/VRPlayerRenderer.java b/common/src/main/java/org/vivecraft/client/render/VRPlayerRenderer.java index 27a0f052b..94535cd26 100644 --- a/common/src/main/java/org/vivecraft/client/render/VRPlayerRenderer.java +++ b/common/src/main/java/org/vivecraft/client/render/VRPlayerRenderer.java @@ -7,6 +7,7 @@ import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.layers.RenderLayer; import net.minecraft.client.renderer.entity.player.PlayerRenderer; import net.minecraft.world.phys.Vec3; import org.vivecraft.client.VRPlayersClient; @@ -34,6 +35,10 @@ public VRPlayerRenderer(EntityRendererProvider.Context context, boolean slim, bo this.addLayer(new HMDLayer(this)); } + public boolean hasLayerType(RenderLayer renderLayer) { + return this.layers.stream().anyMatch(layer -> layer.getClass() == renderLayer.getClass()); + } + @Override public void render(AbstractClientPlayer entityIn, float pEntityYaw, float pPartialTicks, PoseStack matrixStackIn, MultiBufferSource pBuffer, int pPackedLight) { diff --git a/common/src/main/java/org/vivecraft/client/utils/UpdateChecker.java b/common/src/main/java/org/vivecraft/client/utils/UpdateChecker.java index dd59bd9c8..326ebf2a3 100644 --- a/common/src/main/java/org/vivecraft/client/utils/UpdateChecker.java +++ b/common/src/main/java/org/vivecraft/client/utils/UpdateChecker.java @@ -45,7 +45,7 @@ public static boolean checkForUpdates() { } try { - String apiURL = "https://api.modrinth.com/v2/project/vivecraft/version?loaders=[%22" + Xplat.getModloader() + "%22]&game_versions=[%22" + SharedConstants.VERSION_STRING + "%22]"; + String apiURL = "https://api.modrinth.com/v2/project/vivecraft/version?loaders=[%22" + Xplat.getModloader().name + "%22]&game_versions=[%22" + SharedConstants.VERSION_STRING + "%22]"; HttpURLConnection conn = (HttpURLConnection) new URL(apiURL).openConnection(); // 10 seconds read and connect timeout conn.setConnectTimeout(10000); @@ -76,7 +76,7 @@ public static boolean checkForUpdates() { // sort the versions, modrinth doesn't guarantee them to be sorted. Collections.sort(versions); - String currentVersionNumber = Xplat.getModVersion() + "-" + Xplat.getModloader(); + String currentVersionNumber = Xplat.getModVersion() + "-" + Xplat.getModloader().name; Version current = new Version(currentVersionNumber, currentVersionNumber, ""); for (Version v : versions) { diff --git a/common/src/main/java/org/vivecraft/client_vr/VRState.java b/common/src/main/java/org/vivecraft/client_vr/VRState.java index bc5f31ba3..9e841bc4f 100644 --- a/common/src/main/java/org/vivecraft/client_vr/VRState.java +++ b/common/src/main/java/org/vivecraft/client_vr/VRState.java @@ -19,6 +19,7 @@ import org.vivecraft.mod_compat_vr.ShadersHelper; import org.vivecraft.mod_compat_vr.optifine.OptifineHelper; +import java.io.File; import java.lang.management.ManagementFactory; import java.lang.management.MemoryManagerMXBean; @@ -44,7 +45,14 @@ public static void initializeVR() { // TODO: move this into the init, does mean all callocs need to be done later // check that the right lwjgl version is loaded that we ship the openvr part of if (!Version.getVersion().startsWith("3.3.1")) { - throw new RenderConfigException("VR Init Error", Component.translatable("vivecraft.messages.rendersetupfailed", I18n.get("vivecraft.messages.invalidlwjgl", Version.getVersion(), "3.3.1"), "OpenVR_LWJGL")); + String suppliedJar = ""; + try { + suppliedJar = new File(Version.class.getProtectionDomain().getCodeSource().getLocation().getPath()).getName(); + } catch (Exception e) { + VRSettings.logger.error("couldn't check lwjgl source:", e); + } + + throw new RenderConfigException("VR Init Error", Component.translatable("vivecraft.messages.rendersetupfailed", I18n.get("vivecraft.messages.invalidlwjgl", Version.getVersion(), "3.3.1", suppliedJar), "OpenVR_LWJGL")); } dh.vr = new MCOpenVR(Minecraft.getInstance(), dh); @@ -113,6 +121,7 @@ public static void initializeVR() { } catch (RenderConfigException renderConfigException) { vrEnabled = false; destroyVR(true); + renderConfigException.printStackTrace(); Minecraft.getInstance().setScreen(new ErrorScreen(renderConfigException.title, renderConfigException.error)); } catch (Throwable e) { vrEnabled = false; diff --git a/common/src/main/java/org/vivecraft/client_vr/extensions/MinecraftExtension.java b/common/src/main/java/org/vivecraft/client_vr/extensions/MinecraftExtension.java index 975250b11..6f0d36c6b 100644 --- a/common/src/main/java/org/vivecraft/client_vr/extensions/MinecraftExtension.java +++ b/common/src/main/java/org/vivecraft/client_vr/extensions/MinecraftExtension.java @@ -3,4 +3,5 @@ public interface MinecraftExtension { void vivecraft$notifyMirror(String buttonDisplayString, boolean b, int i); + void vivecraft$drawProfiler(); } diff --git a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/InteractTracker.java b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/InteractTracker.java index 3c41bf46e..9fc94d759 100644 --- a/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/InteractTracker.java +++ b/common/src/main/java/org/vivecraft/client_vr/gameplay/trackers/InteractTracker.java @@ -186,7 +186,7 @@ public void doProcess(LocalPlayer player) { } } - if (!this.active[j]) { + if (this.dh.vrSettings.realisticEntityInteractEnabled && !this.active[j]) { int k = Mth.floor(vec3.x); int l = Mth.floor(vec3.y); int i = Mth.floor(vec3.z); @@ -204,7 +204,7 @@ public void doProcess(LocalPlayer player) { } } - if (!this.active[j]) { + if (this.dh.vrSettings.realisticBlockInteractEnabled && !this.active[j]) { BlockPos blockpos = null; blockpos = BlockPos.containing(vec3); BlockState blockstate = this.mc.level.getBlockState(blockpos); diff --git a/common/src/main/java/org/vivecraft/client_vr/provider/nullvr/NullVR.java b/common/src/main/java/org/vivecraft/client_vr/provider/nullvr/NullVR.java index 34f57959f..09ff0186b 100644 --- a/common/src/main/java/org/vivecraft/client_vr/provider/nullvr/NullVR.java +++ b/common/src/main/java/org/vivecraft/client_vr/provider/nullvr/NullVR.java @@ -95,11 +95,11 @@ public void poll(long frameIndex) { this.updateAim(); - this.controllerPose[0].M[0][3] = 0.3F; + this.controllerPose[0].M[0][3] = this.dh.vrSettings.reverseHands ? -0.3F : 0.3F; this.controllerPose[0].M[1][3] = 1.2F; this.controllerPose[0].M[2][3] = -0.5F; - this.controllerPose[1].M[0][3] = -0.3F; + this.controllerPose[1].M[0][3] = this.dh.vrSettings.reverseHands ? 0.3F : -0.3F; this.controllerPose[1].M[1][3] = 1.2F; this.controllerPose[1].M[2][3] = -0.5F; diff --git a/common/src/main/java/org/vivecraft/client_vr/render/VivecraftItemRendering.java b/common/src/main/java/org/vivecraft/client_vr/render/VivecraftItemRendering.java index 41a44e037..ed01b175f 100644 --- a/common/src/main/java/org/vivecraft/client_vr/render/VivecraftItemRendering.java +++ b/common/src/main/java/org/vivecraft/client_vr/render/VivecraftItemRendering.java @@ -233,7 +233,7 @@ public static void applyFirstPersonItemTransforms(PoseStack pMatrixStack, Vivecr rotation.mul(Axis.XP.rotationDegrees(-45.0F)); rotation.mul(Axis.XP.rotationDegrees((float) gunAngle)); } else if (rendertype == VivecraftItemTransformType.Shield) { - boolean reverse = dh.vrSettings.reverseHands && !dh.vrSettings.seated; + boolean reverse = dh.vrSettings.reverseHands; if (reverse) { k *= -1; } diff --git a/common/src/main/java/org/vivecraft/client_vr/render/helpers/RenderHelper.java b/common/src/main/java/org/vivecraft/client_vr/render/helpers/RenderHelper.java index dfc45a291..ec9780d73 100644 --- a/common/src/main/java/org/vivecraft/client_vr/render/helpers/RenderHelper.java +++ b/common/src/main/java/org/vivecraft/client_vr/render/helpers/RenderHelper.java @@ -83,23 +83,25 @@ public static Vec3 getControllerRenderPos(int c) { return dataHolder.vrPlayer.vrdata_world_render.getController(c).getPosition(); } else { Vec3 out = null; + int mainHand = InteractionHand.MAIN_HAND.ordinal(); + if (dataHolder.vrSettings.reverseHands) { + c = 1 - c; + mainHand = InteractionHand.OFF_HAND.ordinal(); + } if (mc.getCameraEntity() != null && mc.level != null) { Vec3 dir = dataHolder.vrPlayer.vrdata_world_render.hmd.getDirection(); dir = dir.yRot((float) Math.toRadians(c == 0 ? -35.0D : 35.0D)); dir = new Vec3(dir.x, 0.0D, dir.z); dir = dir.normalize(); - if (TelescopeTracker.isTelescope(mc.player.getUseItem())) { - if (c == 0 && mc.player.getUsedItemHand() == InteractionHand.MAIN_HAND) { - out = dataHolder.vrPlayer.vrdata_world_render.eye0.getPosition() - .add(dataHolder.vrPlayer.vrdata_world_render.hmd.getDirection() - .scale(0.2 * dataHolder.vrPlayer.vrdata_world_render.worldScale)); - } - if (c == 1 && mc.player.getUsedItemHand() == InteractionHand.OFF_HAND) { - out = dataHolder.vrPlayer.vrdata_world_render.eye1.getPosition() - .add(dataHolder.vrPlayer.vrdata_world_render.hmd.getDirection() - .scale(0.2 * dataHolder.vrPlayer.vrdata_world_render.worldScale)); - } + if (TelescopeTracker.isTelescope(mc.player.getUseItem()) && TelescopeTracker.isTelescope(c == mainHand ? mc.player.getMainHandItem() : mc.player.getOffhandItem())) { + // move the controller in front of the eye when using the spyglass + VRData.VRDevicePose eye = c == 0 ? dataHolder.vrPlayer.vrdata_world_render.eye0 : + dataHolder.vrPlayer.vrdata_world_render.eye1; + + out = eye.getPosition() + .add(dataHolder.vrPlayer.vrdata_world_render.hmd.getDirection() + .scale(0.2 * dataHolder.vrPlayer.vrdata_world_render.worldScale)); } if (out == null) { out = dataHolder.vrPlayer.vrdata_world_render.getEye(RenderPass.CENTER).getPosition().add( @@ -125,11 +127,11 @@ public static void setupRenderingAtController(int controller, PoseStack matrix) getSmoothCameraPosition(dataHolder.currentPass, dataHolder.vrPlayer.getVRDataWorld())); matrix.translate(aimSource.x, aimSource.y, aimSource.z); float sc = dataHolder.vrPlayer.vrdata_world_render.worldScale; - if (mc.level != null && TelescopeTracker.isTelescope(mc.player.getUseItem())) { + if (dataHolder.vrSettings.seated && mc.level != null && TelescopeTracker.isTelescope(mc.player.getUseItem()) && TelescopeTracker.isTelescope(controller == 0 ? mc.player.getMainHandItem() : mc.player.getOffhandItem())) { matrix.mulPoseMatrix(dataHolder.vrPlayer.vrdata_world_render.hmd.getMatrix().inverted() .transposed().toMCMatrix()); MethodHolder.rotateDegXp(matrix, 90); - matrix.translate(controller == 0 ? 0.075 * sc : -0.075 * sc, -0.025 * sc, 0.0325 * sc); + matrix.translate(controller == (dataHolder.vrSettings.reverseHands ? 1 : 0) ? 0.075 * sc : -0.075 * sc, -0.025 * sc, 0.0325 * sc); } else { matrix.mulPoseMatrix(dataHolder.vrPlayer.vrdata_world_render.getController(controller) .getMatrix().inverted().transposed().toMCMatrix()); @@ -229,6 +231,12 @@ public static void drawScreen(float f, Screen screen, GuiGraphics guiGraphics) { posestack.translate(0.0D, 0.0D, -11000.0D); RenderSystem.applyModelViewMatrix(); + Matrix4f guiProjection = (new Matrix4f()).setOrtho( + 0.0F, (float) (mc.getWindow().getWidth() / mc.getWindow().getGuiScale()), + (float) (mc.getWindow().getHeight() / mc.getWindow().getGuiScale()), 0.0F, + 1000.0F, 21000.0F); + RenderSystem.setProjectionMatrix(guiProjection, VertexSorting.ORTHOGRAPHIC_Z); + RenderSystem.blendFuncSeparate( GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, diff --git a/common/src/main/java/org/vivecraft/client_vr/render/helpers/VRPassHelper.java b/common/src/main/java/org/vivecraft/client_vr/render/helpers/VRPassHelper.java index 7465654ca..5bb494aee 100644 --- a/common/src/main/java/org/vivecraft/client_vr/render/helpers/VRPassHelper.java +++ b/common/src/main/java/org/vivecraft/client_vr/render/helpers/VRPassHelper.java @@ -4,22 +4,34 @@ import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.shaders.ProgramManager; import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; import net.minecraft.Util; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiGraphics; import net.minecraft.util.Mth; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.block.Blocks; import org.lwjgl.opengl.GL13C; import org.vivecraft.client.Xplat; import org.vivecraft.client.extensions.RenderTargetExtension; +import org.vivecraft.client.utils.Utils; import org.vivecraft.client_vr.ClientDataHolderVR; import org.vivecraft.client_vr.extensions.GameRendererExtension; +import org.vivecraft.client_vr.extensions.GuiExtension; +import org.vivecraft.client_vr.extensions.MinecraftExtension; +import org.vivecraft.client_vr.gameplay.screenhandlers.KeyboardHandler; +import org.vivecraft.client_vr.gameplay.screenhandlers.RadialHandler; +import org.vivecraft.client_vr.render.RenderConfigException; import org.vivecraft.client_vr.render.RenderPass; import org.vivecraft.client_vr.render.VRShaders; import org.vivecraft.client_vr.settings.VRSettings; +import org.vivecraft.client_xr.render_pass.RenderPassManager; +import org.vivecraft.client_xr.render_pass.WorldRenderPass; import org.vivecraft.mod_compat_vr.iris.IrisHelper; import org.vivecraft.mod_compat_vr.optifine.OptifineHelper; +import java.util.List; + public class VRPassHelper { private static final Minecraft mc = Minecraft.getInstance(); @@ -217,6 +229,136 @@ public static void renderSingleView(RenderPass eye, float partialTicks, long nan } } + public static void renderAndSubmit(boolean renderLevel, long nanoTime, float actualPartialTicks) { + // still rendering + mc.getProfiler().push("gameRenderer"); + + mc.getProfiler().push("VR guis"); + + // some mods mess with the depth mask? + RenderSystem.depthMask(true); + + mc.getProfiler().push("gui cursor"); + // draw cursor on Gui Layer + if (mc.screen != null || !mc.mouseHandler.isMouseGrabbed()) { + PoseStack poseStack = RenderSystem.getModelViewStack(); + poseStack.pushPose(); + poseStack.setIdentity(); + poseStack.translate(0.0f, 0.0f, -11000.0f); + RenderSystem.applyModelViewMatrix(); + + int x = (int) (Minecraft.getInstance().mouseHandler.xpos() * (double) Minecraft.getInstance().getWindow().getGuiScaledWidth() / (double) Minecraft.getInstance().getWindow().getScreenWidth()); + int y = (int) (Minecraft.getInstance().mouseHandler.ypos() * (double) Minecraft.getInstance().getWindow().getGuiScaledHeight() / (double) Minecraft.getInstance().getWindow().getScreenHeight()); + ((GuiExtension) mc.gui).vivecraft$drawMouseMenuQuad(x, y); + + poseStack.popPose(); + RenderSystem.applyModelViewMatrix(); + } + + mc.getProfiler().popPush("fps pie"); + // draw debug pie + ((MinecraftExtension) mc).vivecraft$drawProfiler(); + + // pop pose that we pushed before the gui + RenderSystem.getModelViewStack().popPose(); + RenderSystem.applyModelViewMatrix(); + + // generate mipmaps + // TODO: does this do anything? + mc.mainRenderTarget.bindRead(); + ((RenderTargetExtension) mc.mainRenderTarget).vivecraft$genMipMaps(); + mc.mainRenderTarget.unbindRead(); + + mc.getProfiler().popPush("2D Keyboard"); + GuiGraphics guiGraphics = new GuiGraphics(mc, mc.renderBuffers().bufferSource()); + if (KeyboardHandler.Showing && !dataHolder.vrSettings.physicalKeyboard) { + mc.mainRenderTarget = KeyboardHandler.Framebuffer; + mc.mainRenderTarget.clear(Minecraft.ON_OSX); + mc.mainRenderTarget.bindWrite(true); + RenderHelper.drawScreen(actualPartialTicks, KeyboardHandler.UI, guiGraphics); + guiGraphics.flush(); + } + + mc.getProfiler().popPush("Radial Menu"); + if (RadialHandler.isShowing()) { + mc.mainRenderTarget = RadialHandler.Framebuffer; + mc.mainRenderTarget.clear(Minecraft.ON_OSX); + mc.mainRenderTarget.bindWrite(true); + RenderHelper.drawScreen(actualPartialTicks, RadialHandler.UI, guiGraphics); + guiGraphics.flush(); + } + mc.getProfiler().pop(); + checkGLError("post 2d "); + + // done with guis + mc.getProfiler().pop(); + + // render the different vr passes + List list = dataHolder.vrRenderer.getRenderPasses(); + dataHolder.isFirstPass = true; + for (RenderPass renderpass : list) { + dataHolder.currentPass = renderpass; + + switch (renderpass) { + case LEFT, RIGHT -> RenderPassManager.setWorldRenderPass(WorldRenderPass.stereoXR); + case CENTER -> RenderPassManager.setWorldRenderPass(WorldRenderPass.center); + case THIRD -> RenderPassManager.setWorldRenderPass(WorldRenderPass.mixedReality); + case SCOPEL -> RenderPassManager.setWorldRenderPass(WorldRenderPass.leftTelescope); + case SCOPER -> RenderPassManager.setWorldRenderPass(WorldRenderPass.rightTelescope); + case CAMERA -> RenderPassManager.setWorldRenderPass(WorldRenderPass.camera); + } + + mc.getProfiler().push("Eye:" + dataHolder.currentPass); + mc.getProfiler().push("setup"); + mc.mainRenderTarget.bindWrite(true); + mc.getProfiler().pop(); + VRPassHelper.renderSingleView(renderpass, actualPartialTicks, nanoTime, renderLevel); + mc.getProfiler().pop(); + + if (dataHolder.grabScreenShot) { + boolean flag; + + if (list.contains(RenderPass.CAMERA)) { + flag = renderpass == RenderPass.CAMERA; + } else if (list.contains(RenderPass.CENTER)) { + flag = renderpass == RenderPass.CENTER; + } else { + flag = dataHolder.vrSettings.displayMirrorLeftEye ? + renderpass == RenderPass.LEFT : + renderpass == RenderPass.RIGHT; + } + + if (flag) { + RenderTarget rendertarget = mc.mainRenderTarget; + + if (renderpass == RenderPass.CAMERA) { + rendertarget = dataHolder.vrRenderer.cameraFramebuffer; + } + + mc.mainRenderTarget.unbindWrite(); + Utils.takeScreenshot(rendertarget); + mc.getWindow().updateDisplay(); + dataHolder.grabScreenShot = false; + } + } + + dataHolder.isFirstPass = false; + } + // now we are done with rendering + mc.getProfiler().pop(); + + dataHolder.vrPlayer.postRender(actualPartialTicks); + mc.getProfiler().push("Display/Reproject"); + + try { + dataHolder.vrRenderer.endFrame(); + } catch (RenderConfigException exception) { + VRSettings.logger.error(exception.toString()); + } + mc.getProfiler().pop(); + checkGLError("post submit "); + } + private static void checkGLError(String string) { int i = GlStateManager._getError(); if (i != 0) { diff --git a/common/src/main/java/org/vivecraft/client_vr/settings/VRSettings.java b/common/src/main/java/org/vivecraft/client_vr/settings/VRSettings.java index 70c42228a..42e0d3eee 100644 --- a/common/src/main/java/org/vivecraft/client_vr/settings/VRSettings.java +++ b/common/src/main/java/org/vivecraft/client_vr/settings/VRSettings.java @@ -271,6 +271,10 @@ public enum UpdateType implements OptionEnum { public boolean realisticRowEnabled = true; @SettingField(VrOptions.REALISTIC_DISMOUNT) public boolean realisticDismountEnabled = true; + @SettingField(VrOptions.REALISTIC_BLOCK_INTERACT) + public boolean realisticBlockInteractEnabled = true; + @SettingField(VrOptions.REALISTIC_ENTITY_INTERACT) + public boolean realisticEntityInteractEnabled = true; @SettingField(VrOptions.BACKPACK_SWITCH) public boolean backpackSwitching = true; @SettingField(VrOptions.PHYSICAL_GUI) @@ -1624,6 +1628,8 @@ Object loadOption(String value) { REALISTIC_SWIM(false, true), // Roomscale Swimming REALISTIC_ROW(false, true), // Roomscale Rowing REALISTIC_DISMOUNT(false, true), // Roomscale Dismounting + REALISTIC_BLOCK_INTERACT(false, true), // Roomscale Block Interaction + REALISTIC_ENTITY_INTERACT(false, true), // Roomscale Entity Interaction WALK_MULTIPLIER(true, false, 1f, 10f, 0.1f, 1), // Walking Multiplier FREEMOVE_MODE(false, true) { // Free Move Type diff --git a/common/src/main/java/org/vivecraft/common/CommonDataHolder.java b/common/src/main/java/org/vivecraft/common/CommonDataHolder.java index 99855b0b8..1edce3be8 100644 --- a/common/src/main/java/org/vivecraft/common/CommonDataHolder.java +++ b/common/src/main/java/org/vivecraft/common/CommonDataHolder.java @@ -16,7 +16,7 @@ public CommonDataHolder() { modVersion = version[1]; } - versionIdentifier = "Vivecraft-" + mcVersion + "-" + Xplat.getModloader() + "-" + modVersion; + versionIdentifier = "Vivecraft-" + mcVersion + "-" + Xplat.getModloader().name + "-" + modVersion; } public static CommonDataHolder getInstance() { diff --git a/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/EntityRenderDispatcherMixin.java b/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/EntityRenderDispatcherMixin.java index 4dbbdde63..aa5777f03 100644 --- a/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/EntityRenderDispatcherMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/EntityRenderDispatcherMixin.java @@ -96,7 +96,7 @@ public abstract class EntityRenderDispatcherMixin implements ResourceManagerRelo vivecraft$skinMapVR.clear(); } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/EntityRenderers;createPlayerRenderers(Lnet/minecraft/client/renderer/entity/EntityRendererProvider$Context;)Ljava/util/Map;", shift = Shift.AFTER), + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/EntityRenderers;createPlayerRenderers(Lnet/minecraft/client/renderer/entity/EntityRendererProvider$Context;)Ljava/util/Map;"), method = "onResourceManagerReload", locals = LocalCapture.CAPTURE_FAILEXCEPTION) public void vivecraft$reload(ResourceManager p_174004_, CallbackInfo info, EntityRendererProvider.Context context) { this.vivecraft$playerRendererVRSeated = new VRPlayerRenderer(context, false, true); diff --git a/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/ItemRendererVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/ItemRendererVRMixin.java index 7e2bf71d5..41a3e9d8d 100644 --- a/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/ItemRendererVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/ItemRendererVRMixin.java @@ -11,6 +11,7 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.vivecraft.client_vr.ClientDataHolderVR; +import org.vivecraft.client_vr.VRState; import org.vivecraft.client_vr.gameplay.trackers.ClimbTracker; import org.vivecraft.client_vr.gameplay.trackers.TelescopeTracker; @@ -23,7 +24,7 @@ public class ItemRendererVRMixin { @ModifyVariable(at = @At(value = "STORE"), method = "getModel") public BakedModel vivecraft$modelOverride(BakedModel bakedModel, ItemStack itemStack) { - if (itemStack.is(Items.SPYGLASS)) { + if (VRState.vrRunning && itemStack.is(Items.SPYGLASS)) { return itemModelShaper.getModelManager().getModel(TelescopeTracker.scopeModel); } if (ClientDataHolderVR.getInstance().climbTracker.isClaws(itemStack)) { diff --git a/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/LivingEntityRendererMixin.java b/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/LivingEntityRendererMixin.java index 498785933..e0d679d46 100644 --- a/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/LivingEntityRendererMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client/renderer/entity/LivingEntityRendererMixin.java @@ -46,12 +46,14 @@ protected LivingEntityRendererMixin(EntityRendererProvider.Context context) { super(context); } + @SuppressWarnings("unchecked") @Inject(at = @At("HEAD"), method = "addLayer") public void vivecraft$copyLayer(RenderLayer renderLayer, CallbackInfoReturnable cir) { // check if the layer gets added from the PlayerRenderer, we don't want to copy, if we add it to the VRPlayerRenderer // also check that the VRPlayerRenderers were created, this method also gets called in the constructor, // those default Layers already are added to the VRPlayerRenderer there - if ((Object) this.getClass() == PlayerRenderer.class && !((EntityRenderDispatcherExtension) Minecraft.getInstance().getEntityRenderDispatcher()).vivecraft$getSkinMapVRSeated().isEmpty()) { + EntityRenderDispatcherExtension renderExtension = (EntityRenderDispatcherExtension) entityRenderDispatcher; + if ((Object) this.getClass() == PlayerRenderer.class && !renderExtension.vivecraft$getSkinMapVRSeated().isEmpty()) { // try to find a suitable constructor, so we can create a new Object without issues Constructor constructor = null; @@ -80,21 +82,23 @@ protected LivingEntityRendererMixin(EntityRendererProvider.Context context) { // if no suitable constructor was found, use do a basic Object.clone call, and replace the parent of the copy if (constructor == null) { // do a hacky clone, and replace parent - if (((PlayerModel) model).slim) { - vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("slim")); - vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("slim")); - } else { - vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("default")); - vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("default")); + if (((PlayerModel) model).slim && + !renderExtension.vivecraft$getSkinMapVRSeated().get("slim").hasLayerType(renderLayer)) { + vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) renderExtension.vivecraft$getSkinMapVRSeated().get("slim")); + vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) renderExtension.vivecraft$getSkinMapVR().get("slim")); + } else if (!renderExtension.vivecraft$getSkinMapVRSeated().get("default").hasLayerType(renderLayer)) { + vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) renderExtension.vivecraft$getSkinMapVRSeated().get("default")); + vivecraft$addLayerClone(renderLayer, (LivingEntityRenderer) renderExtension.vivecraft$getSkinMapVR().get("default")); } } else { // make a new instance with the vr model as parent - if (((PlayerModel) model).slim) { - vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("slim")); - vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("slim")); - } else { - vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVRSeated().get("default")); - vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) ((EntityRenderDispatcherExtension) entityRenderDispatcher).vivecraft$getSkinMapVR().get("default")); + if (((PlayerModel) model).slim && + !renderExtension.vivecraft$getSkinMapVRSeated().get("slim").hasLayerType(renderLayer)) { + vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) renderExtension.vivecraft$getSkinMapVRSeated().get("slim")); + vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) renderExtension.vivecraft$getSkinMapVR().get("slim")); + } else if (!renderExtension.vivecraft$getSkinMapVRSeated().get("default").hasLayerType(renderLayer)) { + vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) renderExtension.vivecraft$getSkinMapVRSeated().get("default")); + vivecraft$addLayerConstructor(constructor, type, (LivingEntityRenderer) renderExtension.vivecraft$getSkinMapVR().get("default")); } } } @@ -103,6 +107,7 @@ protected LivingEntityRendererMixin(EntityRendererProvider.Context context) { /** * does a basic Object.clone() copy */ + @SuppressWarnings("unchecked") @Unique private void vivecraft$addLayerClone(RenderLayer renderLayer, LivingEntityRenderer target) { try { @@ -118,6 +123,7 @@ protected LivingEntityRendererMixin(EntityRendererProvider.Context context) { /** * uses the provided constructor, to create a new RenderLayer Instance */ + @SuppressWarnings("unchecked") @Unique private void vivecraft$addLayerConstructor(Constructor constructor, RenderLayerTypes.LayerType type, LivingEntityRenderer target) { try { @@ -128,12 +134,12 @@ protected LivingEntityRendererMixin(EntityRendererProvider.Context context) { case PARENT_MODEL_MODEL -> { if (((PlayerModel) model).slim) { target.addLayer((RenderLayer) constructor.newInstance(target, - new HumanoidModel(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.PLAYER_SLIM_INNER_ARMOR)), - new HumanoidModel(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.PLAYER_SLIM_OUTER_ARMOR)))); + new HumanoidModel<>(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.PLAYER_SLIM_INNER_ARMOR)), + new HumanoidModel<>(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.PLAYER_SLIM_OUTER_ARMOR)))); } else { target.addLayer((RenderLayer) constructor.newInstance(target, - new HumanoidModel(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.PLAYER_INNER_ARMOR)), - new HumanoidModel(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.PLAYER_OUTER_ARMOR)))); + new HumanoidModel<>(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.PLAYER_INNER_ARMOR)), + new HumanoidModel<>(Minecraft.getInstance().getEntityModels().bakeLayer(ModelLayers.PLAYER_OUTER_ARMOR)))); } } } diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java index 6df0b274c..591c458bc 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/MinecraftVRMixin.java @@ -63,8 +63,6 @@ import org.vivecraft.client_vr.VRState; import org.vivecraft.client_vr.extensions.*; import org.vivecraft.client_vr.gameplay.screenhandlers.GuiHandler; -import org.vivecraft.client_vr.gameplay.screenhandlers.KeyboardHandler; -import org.vivecraft.client_vr.gameplay.screenhandlers.RadialHandler; import org.vivecraft.client_vr.gameplay.trackers.TelescopeTracker; import org.vivecraft.client_vr.menuworlds.MenuWorldDownloader; import org.vivecraft.client_vr.menuworlds.MenuWorldExporter; @@ -73,12 +71,9 @@ import org.vivecraft.client_vr.render.RenderPass; import org.vivecraft.client_vr.render.VRFirstPersonArmSwing; import org.vivecraft.client_vr.render.VRShaders; -import org.vivecraft.client_vr.render.helpers.RenderHelper; -import org.vivecraft.client_vr.render.helpers.VRPassHelper; import org.vivecraft.client_vr.settings.VRHotkeys; import org.vivecraft.client_vr.settings.VRSettings; import org.vivecraft.client_xr.render_pass.RenderPassManager; -import org.vivecraft.client_xr.render_pass.WorldRenderPass; import org.vivecraft.common.utils.math.Vector3; import org.vivecraft.mod_compat_vr.optifine.OptifineHelper; @@ -392,140 +387,6 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { } } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiling/ProfilerFiller;pop()V", ordinal = 4, shift = At.Shift.AFTER), method = "runTick", locals = LocalCapture.CAPTURE_FAILHARD) - public void vivecraft$renderVRPasses(boolean renderLevel, CallbackInfo ci, long nanoTime) { - if (VRState.vrRunning) { - // still rendering - this.profiler.push("gameRenderer"); - - this.profiler.push("VR guis"); - - // some mods mess with the depth mask? - RenderSystem.depthMask(true); - - this.profiler.push("gui cursor"); - // draw cursor on Gui Layer - if (this.screen != null || !mouseHandler.isMouseGrabbed()) { - PoseStack poseStack = RenderSystem.getModelViewStack(); - poseStack.pushPose(); - poseStack.setIdentity(); - poseStack.translate(0.0f, 0.0f, -11000.0f); - RenderSystem.applyModelViewMatrix(); - - int x = (int) (Minecraft.getInstance().mouseHandler.xpos() * (double) Minecraft.getInstance().getWindow().getGuiScaledWidth() / (double) Minecraft.getInstance().getWindow().getScreenWidth()); - int y = (int) (Minecraft.getInstance().mouseHandler.ypos() * (double) Minecraft.getInstance().getWindow().getGuiScaledHeight() / (double) Minecraft.getInstance().getWindow().getScreenHeight()); - ((GuiExtension) this.gui).vivecraft$drawMouseMenuQuad(x, y); - - poseStack.popPose(); - RenderSystem.applyModelViewMatrix(); - } - - this.profiler.popPush("fps pie"); - // draw debug pie - vivecraft$drawProfiler(); - - // pop pose that we pushed before the gui - RenderSystem.getModelViewStack().popPose(); - RenderSystem.applyModelViewMatrix(); - - // generate mipmaps - // TODO: does this do anything? - mainRenderTarget.bindRead(); - ((RenderTargetExtension) mainRenderTarget).vivecraft$genMipMaps(); - mainRenderTarget.unbindRead(); - - this.profiler.popPush("2D Keyboard"); - float actualPartialTicks = this.pause ? this.pausePartialTick : this.timer.partialTick; - GuiGraphics guiGraphics = new GuiGraphics((Minecraft) (Object) this, renderBuffers.bufferSource()); - if (KeyboardHandler.Showing - && !ClientDataHolderVR.getInstance().vrSettings.physicalKeyboard) { - this.mainRenderTarget = KeyboardHandler.Framebuffer; - this.mainRenderTarget.clear(Minecraft.ON_OSX); - this.mainRenderTarget.bindWrite(true); - RenderHelper.drawScreen(actualPartialTicks, KeyboardHandler.UI, guiGraphics); - guiGraphics.flush(); - } - - this.profiler.popPush("Radial Menu"); - if (RadialHandler.isShowing()) { - this.mainRenderTarget = RadialHandler.Framebuffer; - this.mainRenderTarget.clear(Minecraft.ON_OSX); - this.mainRenderTarget.bindWrite(true); - RenderHelper.drawScreen(actualPartialTicks, RadialHandler.UI, guiGraphics); - guiGraphics.flush(); - } - this.profiler.pop(); - this.vivecraft$checkGLError("post 2d "); - - // done with guis - this.profiler.pop(); - - // render the different vr passes - List list = ClientDataHolderVR.getInstance().vrRenderer.getRenderPasses(); - ClientDataHolderVR.getInstance().isFirstPass = true; - for (RenderPass renderpass : list) { - ClientDataHolderVR.getInstance().currentPass = renderpass; - - switch (renderpass) { - case LEFT, RIGHT -> RenderPassManager.setWorldRenderPass(WorldRenderPass.stereoXR); - case CENTER -> RenderPassManager.setWorldRenderPass(WorldRenderPass.center); - case THIRD -> RenderPassManager.setWorldRenderPass(WorldRenderPass.mixedReality); - case SCOPEL -> RenderPassManager.setWorldRenderPass(WorldRenderPass.leftTelescope); - case SCOPER -> RenderPassManager.setWorldRenderPass(WorldRenderPass.rightTelescope); - case CAMERA -> RenderPassManager.setWorldRenderPass(WorldRenderPass.camera); - } - - this.profiler.push("Eye:" + ClientDataHolderVR.getInstance().currentPass); - this.profiler.push("setup"); - this.mainRenderTarget.bindWrite(true); - this.profiler.pop(); - VRPassHelper.renderSingleView(renderpass, actualPartialTicks, nanoTime, renderLevel); - this.profiler.pop(); - - if (ClientDataHolderVR.getInstance().grabScreenShot) { - boolean flag; - - if (list.contains(RenderPass.CAMERA)) { - flag = renderpass == RenderPass.CAMERA; - } else if (list.contains(RenderPass.CENTER)) { - flag = renderpass == RenderPass.CENTER; - } else { - flag = ClientDataHolderVR.getInstance().vrSettings.displayMirrorLeftEye ? renderpass == RenderPass.LEFT - : renderpass == RenderPass.RIGHT; - } - - if (flag) { - RenderTarget rendertarget = this.mainRenderTarget; - - if (renderpass == RenderPass.CAMERA) { - rendertarget = ClientDataHolderVR.getInstance().vrRenderer.cameraFramebuffer; - } - - this.mainRenderTarget.unbindWrite(); - Utils.takeScreenshot(rendertarget); - this.window.updateDisplay(); - ClientDataHolderVR.getInstance().grabScreenShot = false; - } - } - - ClientDataHolderVR.getInstance().isFirstPass = false; - } - // now we are done with rendering - this.profiler.pop(); - - ClientDataHolderVR.getInstance().vrPlayer.postRender(actualPartialTicks); - this.profiler.push("Display/Reproject"); - - try { - ClientDataHolderVR.getInstance().vrRenderer.endFrame(); - } catch (RenderConfigException exception) { - VRSettings.logger.error(exception.toString()); - } - this.profiler.pop(); - this.vivecraft$checkGLError("post submit "); - } - } - @Redirect(at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;fpsPieResults:Lnet/minecraft/util/profiling/ProfileResults;"), method = "runTick") public ProfileResults vivecraft$cancelRegularFpsPie(Minecraft instance) { return VRState.vrRunning ? null : fpsPieResults; @@ -967,7 +828,8 @@ public abstract class MinecraftVRMixin implements MinecraftExtension { } @Unique - private void vivecraft$drawProfiler() { + @Override + public void vivecraft$drawProfiler() { if (this.fpsPieResults != null) { this.profiler.push("fpsPie"); GuiGraphics guiGraphics = new GuiGraphics((Minecraft) (Object) this, renderBuffers.bufferSource()); diff --git a/common/src/main/java/org/vivecraft/mixin/client_vr/renderer/entity/EntityRenderDispatcherVRMixin.java b/common/src/main/java/org/vivecraft/mixin/client_vr/renderer/entity/EntityRenderDispatcherVRMixin.java index 39231ead6..77ea8eab5 100644 --- a/common/src/main/java/org/vivecraft/mixin/client_vr/renderer/entity/EntityRenderDispatcherVRMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/client_vr/renderer/entity/EntityRenderDispatcherVRMixin.java @@ -62,7 +62,7 @@ public abstract class EntityRenderDispatcherVRMixin implements ResourceManagerRe } } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/EntityRenderers;createPlayerRenderers(Lnet/minecraft/client/renderer/entity/EntityRendererProvider$Context;)Ljava/util/Map;", shift = At.Shift.AFTER), + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/entity/EntityRenderers;createPlayerRenderers(Lnet/minecraft/client/renderer/entity/EntityRendererProvider$Context;)Ljava/util/Map;"), method = "onResourceManagerReload(Lnet/minecraft/server/packs/resources/ResourceManager;)V", locals = LocalCapture.CAPTURE_FAILEXCEPTION) public void vivecraft$reload(ResourceManager resourceManager, CallbackInfo ci, EntityRendererProvider.Context context) { this.vivecraft$armRenderer = new VRArmRenderer(context, false); diff --git a/common/src/main/java/org/vivecraft/mixin/server/MinecraftServerMixin.java b/common/src/main/java/org/vivecraft/mixin/server/MinecraftServerMixin.java index cd8b93ea4..7e6081eda 100644 --- a/common/src/main/java/org/vivecraft/mixin/server/MinecraftServerMixin.java +++ b/common/src/main/java/org/vivecraft/mixin/server/MinecraftServerMixin.java @@ -3,7 +3,13 @@ import net.minecraft.server.MinecraftServer; import org.spongepowered.asm.mixin.Mixin; 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; +import org.vivecraft.client.Xplat; import org.vivecraft.server.MinecraftServerExt; +import org.vivecraft.server.ServerNetworking; +import org.vivecraft.server.ServerUtil; import org.vivecraft.server.ServerVivePlayer; import java.util.HashMap; @@ -21,4 +27,12 @@ public class MinecraftServerMixin implements MinecraftServerExt { public Map vivecraft$getPlayersWithVivecraft() { return this.vivecraft$playersWithVivecraft; } + + @Inject(at = @At("HEAD"), method = "stopServer") + private void vivecraft$stopExecutor(CallbackInfo ci) { + if (Xplat.isDedicatedServer()) { + ServerNetworking.LOGGER.info("shutting down vivecraft scheduler"); + ServerUtil.scheduler.shutdownNow(); + } + } } diff --git a/common/src/main/resources/assets/vivecraft/lang/de_de.json b/common/src/main/resources/assets/vivecraft/lang/de_de.json index 84d30f280..7030aefdb 100644 --- a/common/src/main/resources/assets/vivecraft/lang/de_de.json +++ b/common/src/main/resources/assets/vivecraft/lang/de_de.json @@ -155,6 +155,8 @@ "vivecraft.options.REALISTIC_SWIM": "Raumskala Schwimmen", "vivecraft.options.REALISTIC_ROW": "Raumskala Rudern", "vivecraft.options.REALISTIC_DISMOUNT": "Raumskala Absteigen", + "vivecraft.options.REALISTIC_BLOCK_INTERACT": "Raumskala Blockinteraktion", + "vivecraft.options.REALISTIC_ENTITY_INTERACT": "Raumskala Objektinteraktion", "vivecraft.options.WALK_MULTIPLIER": "Lauf Multiplikator", "vivecraft.options.FREEMOVE_MODE": "Frei Bewegen", "vivecraft.options.VEHICLE_ROTATION": "Vehikel Rotation", @@ -245,6 +247,8 @@ "vivecraft.options.REALISTIC_SWIM.tooltip": "Falls eingeschaltet, erlauben Sie das Schwimmen durch Brustschwimm-Bewegung mit den Controllern.", "vivecraft.options.REALISTIC_ROW.tooltip": "Ruder, Ruder, Ruder dein Boot... wie verrückt mit den Armen.", "vivecraft.options.REALISTIC_DISMOUNT.tooltip": "Steige von Objekten ab, indem du dich einen Meter von ihnen entfernst.\nKann Probleme haben mit großen Objekten von anderen Mods.", + "vivecraft.options.REALISTIC_BLOCK_INTERACT.tooltip": "Erlaubt das Aktivieren von Hebeln, Knöpfen, Truhen und so weiter, indem Sie ihre Hand in diese halten und die Interaktionstaste drücken.", + "vivecraft.options.REALISTIC_ENTITY_INTERACT.tooltip": "Erlaubt das Interagieren mit Objekten, indem Sie ihre Hand in diese halten und die Interaktionstaste drücken.", "vivecraft.options.WALK_MULTIPLIER.tooltip": "Multipliziert Ihre Position im Raum mit einem Faktor.\nErlaubt Ihnen, mehr herumzulaufen, kann aber Bewegungsübelkeit verursachen.", "vivecraft.options.FREEMOVE_MODE.tooltip": "Die Quelle für die Frei Bewegen-Richtung.\n\n Controller: Richtung des nicht dominanten Controllers.\n HMD: Blickrichtung des Headsets.\n Run-In-Place: Die Neigung basiert auf dem Schwingen der Controller. Pitch ist Ihr Headset.\n Raum: Die Neigung ist relativ zu Ihrem VR-Raum nach vorne. Neigung: Die Neigung ist basiert auf Ihr Headset. Dieser Modus ist am besten nur für 180 Setups geeignet.", "vivecraft.options.VEHICLE_ROTATION.tooltip": "Wenn man in einem Vehikel fährt, dreht sich die Welt, während sich das Vehikel dreht. Kann verwirrend sein.", @@ -396,7 +400,7 @@ "vivecraft.messages.nosteamvr": "OpenVR runtime nicht erkannt. Ist SteamVR installiert?", "vivecraft.messages.outdatedsteamvr": "OpenVR konnte nicht alle benötigten Komponenten initialisieren. Vergewissern Sie sich, dass Sie die neuesten Version von SteamVR verwenden.", "vivecraft.messages.steamvrInvalidCharacters": "Ungültige Zeichen im Pfad: \n%s\n\nUm diesen Fehler zu beheben, ändere Minecrafts Spielverzeichnis zu etwas außerhalb des Ordners mit den gekennzeichneten Zeichen.", - "vivecraft.messages.invalidlwjgl": "Nicht unterstützte LWJGL Version geladen.\nGeladene Version: §c%s§r\nBenötigte Version: §2%s§r", + "vivecraft.messages.invalidlwjgl": "Nicht unterstützte LWJGL Version geladen.\nGeladene Version: §c%s§r\nBenötigte Version: §2%s§r\nFalsche LWJGL Version wurde geladen von: %s", "vivecraft.messages.menuworldexportcomplete.1": "Weltexport abgeschlossen... Flächengröße: %d", "vivecraft.messages.menuworldexportcomplete.2": "Gespeichert unter %s", "vivecraft.messages.menuworldexportclientwarning": "WARNUNG: Speichern der Menüwelt mithilfe einer Clientwelt. Daten können unvollständig sein. Es wird empfohlen, Menüwelten im Einzelspielermodus zu speichern.", diff --git a/common/src/main/resources/assets/vivecraft/lang/en_us.json b/common/src/main/resources/assets/vivecraft/lang/en_us.json index 6a7c63b13..358d93e64 100644 --- a/common/src/main/resources/assets/vivecraft/lang/en_us.json +++ b/common/src/main/resources/assets/vivecraft/lang/en_us.json @@ -154,6 +154,8 @@ "vivecraft.options.REALISTIC_SWIM": "Roomscale Swimming", "vivecraft.options.REALISTIC_ROW": "Roomscale Rowing", "vivecraft.options.REALISTIC_DISMOUNT": "Roomscale Dismounting", + "vivecraft.options.REALISTIC_BLOCK_INTERACT": "Roomscale Block Interact", + "vivecraft.options.REALISTIC_ENTITY_INTERACT": "Roomscale Entity Interact", "vivecraft.options.WALK_MULTIPLIER": "Walking Multiplier", "vivecraft.options.FREEMOVE_MODE": "Free Move Type", "vivecraft.options.VEHICLE_ROTATION": "Vehicle Rotation", @@ -244,6 +246,8 @@ "vivecraft.options.REALISTIC_SWIM.tooltip": "If turned on, allow swimming by doing the breaststroke with the controllers.", "vivecraft.options.REALISTIC_ROW.tooltip": "Row, row, row your boat... by flapping your arms like mad.", "vivecraft.options.REALISTIC_DISMOUNT.tooltip": "Dismounts from entities, when walking away 1 meter.\nCan have issues with large modded entities.", + "vivecraft.options.REALISTIC_BLOCK_INTERACT.tooltip": "Allows activating levers, buttons, chests and such by holding your hand in them, and pressing the interact button", + "vivecraft.options.REALISTIC_ENTITY_INTERACT.tooltip": "Allows interacting with entities by holding your hand in them, and pressing the interact button", "vivecraft.options.WALK_MULTIPLIER.tooltip": "Multiplies your position in the room by a factor.\nAllows you to walk around more, but may cause motion sickness.", "vivecraft.options.FREEMOVE_MODE.tooltip": "The source for freemove direction.\n\n Controller: Offhand controller pointing direction.\n HMD: Headset look direction.\n Run-In-Place: Yaw is based on how controllers are swinging. Pitch is your Headset.\n Room: Yaw is relative to your VR room forward. Pitch is your Headset. This mode is best only for 180 setups.", "vivecraft.options.VEHICLE_ROTATION.tooltip": "Riding in a vehicle will rotate the world as the vehicle rotates. May be disorienting.", @@ -395,7 +399,7 @@ "vivecraft.messages.nosteamvr": "OpenVR runtime not detected. Did you install SteamVR?", "vivecraft.messages.outdatedsteamvr": "OpenVR failed to initialize needed components. Make sure you are using the latest version of SteamVR.", "vivecraft.messages.steamvrInvalidCharacters": "Invalid characters in path: \n%s\n\nTo fix this error, change your Minecraft game directory to somewhere outside the folder with marked characters.", - "vivecraft.messages.invalidlwjgl": "Unsupported LWJGL version loaded.\nLoaded version: §c%s§r\nRequired version: §2%s§r", + "vivecraft.messages.invalidlwjgl": "Unsupported LWJGL version loaded.\nLoaded version: §c%s§r\nRequired version: §2%s§r\nWrong LWJGL version was loaded by: %s", "vivecraft.messages.menuworldexportcomplete.1": "World export complete... area size: %d", "vivecraft.messages.menuworldexportcomplete.2": "Saved to %s", "vivecraft.messages.menuworldexportclientwarning": "WARNING: Saving menu world using a client world. Data may be incomplete. It is recommended to save menu worlds in singleplayer.", diff --git a/fabric/src/main/java/org/vivecraft/client/fabric/XplatImpl.java b/fabric/src/main/java/org/vivecraft/client/fabric/XplatImpl.java index 818bea3b9..63c805cbe 100644 --- a/fabric/src/main/java/org/vivecraft/client/fabric/XplatImpl.java +++ b/fabric/src/main/java/org/vivecraft/client/fabric/XplatImpl.java @@ -16,6 +16,7 @@ import net.minecraft.world.level.biome.BiomeSpecialEffects; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.material.FluidState; +import org.vivecraft.client.Xplat; import org.vivecraft.fabric.mixin.world.level.biome.BiomeAccessor; import java.nio.file.Path; @@ -34,8 +35,8 @@ public static boolean isDedicatedServer() { return FabricLoader.getInstance().getEnvironmentType().equals(EnvType.SERVER); } - public static String getModloader() { - return "fabric"; + public static Xplat.ModLoader getModloader() { + return Xplat.ModLoader.FABRIC; } public static String getModVersion() { diff --git a/fabric/src/main/java/org/vivecraft/fabric/mixin/FabricMinecraftVRMixin.java b/fabric/src/main/java/org/vivecraft/fabric/mixin/FabricMinecraftVRMixin.java new file mode 100644 index 000000000..f02ac8439 --- /dev/null +++ b/fabric/src/main/java/org/vivecraft/fabric/mixin/FabricMinecraftVRMixin.java @@ -0,0 +1,34 @@ +package org.vivecraft.fabric.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.Timer; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.vivecraft.client_vr.VRState; +import org.vivecraft.client_vr.render.helpers.VRPassHelper; + +@Mixin(Minecraft.class) +public class FabricMinecraftVRMixin { + + @Shadow + @Final + private Timer timer; + + @Shadow + private volatile boolean pause; + + @Shadow + private float pausePartialTick; + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/util/profiling/ProfilerFiller;pop()V", ordinal = 4, shift = At.Shift.AFTER), method = "runTick", locals = LocalCapture.CAPTURE_FAILHARD) + public void vivecraft$renderVRPassesFabric(boolean renderLevel, CallbackInfo ci, long nanoTime) { + if (VRState.vrRunning) { + VRPassHelper.renderAndSubmit(renderLevel, nanoTime, this.pause ? this.pausePartialTick : this.timer.partialTick); + } + } +} diff --git a/fabric/src/main/resources/vivecraft.fabric.mixins.json b/fabric/src/main/resources/vivecraft.fabric.mixins.json index edc2e79ea..2fa46d534 100644 --- a/fabric/src/main/resources/vivecraft.fabric.mixins.json +++ b/fabric/src/main/resources/vivecraft.fabric.mixins.json @@ -5,6 +5,7 @@ "compatibilityLevel": "JAVA_17", "client": [ "FabricGameRendererVRMixin", + "FabricMinecraftVRMixin", "client.resources.model.FabricModelBakeryMixin", "screenhandler.client.FabricClientNetworkingVRMixin", "world.level.biome.BiomeAccessor" diff --git a/forge/src/main/java/org/vivecraft/client/forge/XplatImpl.java b/forge/src/main/java/org/vivecraft/client/forge/XplatImpl.java index 6ae336f70..c19734541 100644 --- a/forge/src/main/java/org/vivecraft/client/forge/XplatImpl.java +++ b/forge/src/main/java/org/vivecraft/client/forge/XplatImpl.java @@ -17,6 +17,7 @@ import net.minecraftforge.fml.loading.FMLLoader; import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.fml.util.ObfuscationReflectionHelper; +import org.vivecraft.client.Xplat; import java.nio.file.Path; @@ -34,8 +35,8 @@ public static boolean isDedicatedServer() { return FMLEnvironment.dist == Dist.DEDICATED_SERVER; } - public static String getModloader() { - return "forge"; + public static Xplat.ModLoader getModloader() { + return Xplat.ModLoader.FORGE; } public static String getModVersion() { diff --git a/forge/src/main/java/org/vivecraft/forge/mixin/ForgeMinecraftVRMixin.java b/forge/src/main/java/org/vivecraft/forge/mixin/ForgeMinecraftVRMixin.java new file mode 100644 index 000000000..40bf15930 --- /dev/null +++ b/forge/src/main/java/org/vivecraft/forge/mixin/ForgeMinecraftVRMixin.java @@ -0,0 +1,34 @@ +package org.vivecraft.forge.mixin; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.Timer; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import org.vivecraft.client_vr.VRState; +import org.vivecraft.client_vr.render.helpers.VRPassHelper; + +@Mixin(Minecraft.class) +public class ForgeMinecraftVRMixin { + + @Shadow + @Final + private Timer timer; + + @Shadow + private volatile boolean pause; + + @Shadow + private float pausePartialTick; + + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraftforge/event/ForgeEventFactory;onRenderTickEnd(F)V", shift = At.Shift.AFTER), method = "runTick", locals = LocalCapture.CAPTURE_FAILHARD) + public void vivecraft$renderVRPassesForge(boolean renderLevel, CallbackInfo ci, long nanoTime) { + if (VRState.vrRunning) { + VRPassHelper.renderAndSubmit(renderLevel, nanoTime, this.pause ? this.pausePartialTick : this.timer.partialTick); + } + } +} diff --git a/forge/src/main/resources/vivecraft.forge.mixins.json b/forge/src/main/resources/vivecraft.forge.mixins.json index 4f0872ea4..4efe9b33e 100644 --- a/forge/src/main/resources/vivecraft.forge.mixins.json +++ b/forge/src/main/resources/vivecraft.forge.mixins.json @@ -3,6 +3,11 @@ "package": "org.vivecraft.forge.mixin", "plugin": "org.vivecraft.MixinConfig", "compatibilityLevel": "JAVA_17", - "client": ["ForgeGameRendererVRMixin", "ForgeIngameGuiVRMixin", "network.ForgeOpenContainerVRMixin"], + "client": [ + "ForgeGameRendererVRMixin", + "ForgeIngameGuiVRMixin", + "ForgeMinecraftVRMixin", + "network.ForgeOpenContainerVRMixin" + ], "minVersion": "0.8.4" } diff --git a/gradle.properties b/gradle.properties index 9103ecd2d..6f22fe0ef 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ minecraft_version=1.20.1 enabled_platforms=fabric,forge archives_base_name=vivecraft -mod_version=1.1.9 +mod_version=1.1.10 maven_group=org.vivecraft architectury_version=9.1.13