Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add openXR support #291

Draft
wants to merge 18 commits into
base: Multiloader-1.21.4
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ subprojects {
implementation("org.lwjgl:lwjgl-openvr:3.3.2:natives-linux")
implementation("org.lwjgl:lwjgl-openvr:3.3.2:natives-macos")
implementation("org.lwjgl:lwjgl-openvr:3.3.2:natives-windows")

implementation("org.lwjgl:lwjgl-openxr:3.3.2")
implementation("org.lwjgl:lwjgl-openxr:3.3.2:natives-linux")
//implementation("org.lwjgl:lwjgl-openxr:3.3.2:natives-macos")
implementation("org.lwjgl:lwjgl-openxr:3.3.2:natives-windows")
}

tasks.withType(JavaCompile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ public interface RenderTargetExtension {

void vivecraft$setTextid(int texid);

void vivecraft$setColorid(int colorid);

void vivecraft$setUseStencil(boolean useStencil);

boolean vivecraft$getUseStencil();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class GuiRenderOpticsSettings extends GuiVROptionsBase {
VRSettings.VrOptions.HANDHELD_CAMERA_RENDER_SCALE,
VRSettings.VrOptions.HANDHELD_CAMERA_FOV,
VRSettings.VrOptions.RELOAD_EXTERNAL_CAMERA,
VRSettings.VrOptions.MIRROR_EYE
VRSettings.VrOptions.MIRROR_EYE,
};
static VRSettings.VrOptions[] MROptions = new VRSettings.VrOptions[]{
VRSettings.VrOptions.MIXED_REALITY_UNITY_LIKE,
Expand Down
36 changes: 19 additions & 17 deletions common/src/main/java/org/vivecraft/client_vr/VRState.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import org.vivecraft.client_vr.menuworlds.MenuWorldRenderer;
import org.vivecraft.client_vr.provider.nullvr.NullVR;
import org.vivecraft.client_vr.provider.openvr_lwjgl.MCOpenVR;
import org.vivecraft.client_vr.provider.openxr.MCOpenXR;
import org.vivecraft.client_vr.render.RenderConfigException;
import org.vivecraft.client_vr.settings.VRSettings;
import org.vivecraft.client_xr.render_pass.RenderPassManager;
Expand Down Expand Up @@ -40,33 +41,34 @@ public static void initializeVR() {

vrInitialized = true;
ClientDataHolderVR dh = ClientDataHolderVR.getInstance();
if (dh.vrSettings.stereoProviderPluginID == VRSettings.VRProvider.OPENVR) {
// make sure the lwjgl version is the right one
// 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.2")) {
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.2", suppliedJar), "OpenVR_LWJGL"));
Minecraft instance = Minecraft.getInstance();
// make sure the lwjgl version is the right one
// 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.2")) {
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);
}

dh.vr = new MCOpenVR(Minecraft.getInstance(), dh);
} else {
dh.vr = new NullVR(Minecraft.getInstance(), dh);
throw new RenderConfigException("VR Init Error", Component.translatable("vivecraft.messages.rendersetupfailed", I18n.get("vivecraft.messages.invalidlwjgl", Version.getVersion(), "3.3.2", suppliedJar), "OpenVR_LWJGL"));
}
switch (dh.vrSettings.stereoProviderPluginID) {
case OPENVR -> dh.vr = new MCOpenVR(instance, dh);
case OPENXR -> dh.vr = new MCOpenXR(instance, dh);
default -> dh.vr = new NullVR(instance, dh);
}

if (!dh.vr.init()) {
throw new RenderConfigException("VR Init Error", Component.translatable("vivecraft.messages.rendersetupfailed", dh.vr.initStatus, dh.vr.getName()));
}

dh.vrRenderer = dh.vr.createVRRenderer();
dh.vrRenderer.lastGuiScale = Minecraft.getInstance().options.guiScale().get();

dh.vrRenderer.setupRenderConfiguration();
dh.vrRenderer.setupRenderConfiguration(false); //TODO look into why I have the boolean
RenderPassManager.setVanillaRenderPass();

dh.vrPlayer = new VRPlayer();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package org.vivecraft.client_vr;

import com.mojang.blaze3d.pipeline.RenderTarget;
import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Minecraft;
import org.lwjgl.opengl.GL30;
import org.vivecraft.client.Xplat;
import org.vivecraft.client.extensions.RenderTargetExtension;

public class VRTextureTarget extends RenderTarget {

private final String name;

public VRTextureTarget(String name, int width, int height, boolean usedepth, boolean onMac, int texid, boolean depthtex, boolean linearFilter, boolean useStencil) {
super(usedepth);
this.name = name;
Expand All @@ -23,6 +25,17 @@ public VRTextureTarget(String name, int width, int height, boolean usedepth, boo
this.setClearColor(0, 0, 0, 0);
}

public VRTextureTarget(String name, int width, int height, int colorid, int index) {
super(true);
this.name = name;
RenderSystem.assertOnGameThreadOrInit();
this.resize(width, height, Minecraft.ON_OSX);
((RenderTargetExtension) this).vivecraft$setColorid(colorid);
GlStateManager._glBindFramebuffer(GL30.GL_FRAMEBUFFER, frameBufferId);
GL30.glFramebufferTextureLayer(GL30.GL_FRAMEBUFFER, GL30.GL_COLOR_ATTACHMENT0, colorid, 0, index);
this.setClearColor(0, 0, 0, 0);
}

@Override
public String toString() {
StringBuilder stringbuilder = new StringBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import net.minecraft.network.chat.Component;
import org.vivecraft.client.gui.framework.TwoHandedScreen;
import org.vivecraft.client_vr.provider.MCVR;
import org.vivecraft.client_vr.provider.openvr_lwjgl.VRInputAction;
import org.vivecraft.client_vr.provider.control.VRInputAction;

public class GuiRadial extends TwoHandedScreen {
private boolean isShift = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.vivecraft.client_vr.provider;

import org.vivecraft.client_vr.provider.openvr_lwjgl.control.VRInputActionSet;
import org.vivecraft.client_vr.provider.control.VRInputActionSet;

public class ActionParams {
public final VRInputActionSet actionSetOverride;
Expand Down
126 changes: 122 additions & 4 deletions common/src/main/java/org/vivecraft/client_vr/provider/MCVR.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.vivecraft.client_vr.provider;

import com.mojang.blaze3d.platform.InputConstants;
import net.minecraft.client.KeyMapping;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.screens.ChatScreen;
Expand All @@ -25,9 +26,10 @@
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.provider.openvr_lwjgl.VRInputAction;
import org.vivecraft.client_vr.provider.openvr_lwjgl.control.VRInputActionSet;
import org.vivecraft.client_vr.provider.openvr_lwjgl.control.VivecraftMovementInput;
import org.vivecraft.client_vr.provider.control.TrackpadSwipeSampler;
import org.vivecraft.client_vr.provider.control.VRInputAction;
import org.vivecraft.client_vr.provider.control.VRInputActionSet;
import org.vivecraft.client_vr.provider.control.VivecraftMovementInput;
import org.vivecraft.client_vr.render.RenderConfigException;
import org.vivecraft.client_vr.render.RenderPass;
import org.vivecraft.client_vr.settings.VRHotkeys;
Expand Down Expand Up @@ -108,6 +110,8 @@ public abstract class MCVR {
protected int quickTorchPreviousSlot;
protected Map<String, VRInputAction> inputActions = new HashMap<>();
protected Map<String, VRInputAction> inputActionsByKeyBinding = new HashMap<>();
protected final Map<String, TrackpadSwipeSampler> trackpadSwipeSamplers = new HashMap<>();
protected boolean inputInitialized;

public MCVR(Minecraft mc, ClientDataHolderVR dh, VivecraftVRMod vrMod) {
this.mc = mc;
Expand All @@ -131,7 +135,50 @@ public static MCVR get() {

public abstract String getID();

public abstract void processInputs();
public void processInputs() {
if (!this.dh.vrSettings.seated && !ClientDataHolderVR.viewonly && this.inputInitialized) {
for (VRInputAction vrinputaction : this.inputActions.values()) {
if (vrinputaction.isHanded()) {
for (ControllerType controllertype : ControllerType.values()) {
vrinputaction.setCurrentHand(controllertype);
this.processInputAction(vrinputaction);
}
} else {
this.processInputAction(vrinputaction);
}
}

this.processScrollInput(GuiHandler.keyScrollAxis, () ->
{
InputSimulator.scrollMouse(0.0D, 1.0D);
}, () ->
{
InputSimulator.scrollMouse(0.0D, -1.0D);
});
this.processScrollInput(VivecraftVRMod.INSTANCE.keyHotbarScroll, () ->
{
this.changeHotbar(-1);
}, () ->
{
this.changeHotbar(1);
});
this.processSwipeInput(VivecraftVRMod.INSTANCE.keyHotbarSwipeX, () ->
{
this.changeHotbar(1);
}, () ->
{
this.changeHotbar(-1);
}, null, null);
this.processSwipeInput(VivecraftVRMod.INSTANCE.keyHotbarSwipeY, null, null, () ->
{
this.changeHotbar(-1);
}, () ->
{
this.changeHotbar(1);
});
this.ignorePressesNextFrame = false;
}
}

public abstract void destroy();

Expand Down Expand Up @@ -1145,6 +1192,76 @@ protected void changeHotbar(int dir) {
}
}

protected void processInputAction(VRInputAction action) {
if (action.isActive() && action.isEnabledRaw()
// try to prevent double left clicks
&& (!ClientDataHolderVR.getInstance().vrSettings.ingameBindingsInGui
|| !(action.actionSet == VRInputActionSet.INGAME && action.keyBinding.key.getType() == InputConstants.Type.MOUSE && action.keyBinding.key.getValue() == 0 && mc.screen != null))) {
if (action.isButtonChanged()) {
if (action.isButtonPressed() && action.isEnabled()) {
if (!this.ignorePressesNextFrame) {
action.pressBinding();
}
} else {
action.unpressBinding();
}
}
} else {
action.unpressBinding();
}
}

protected void processScrollInput(KeyMapping keyBinding, Runnable upCallback, Runnable downCallback) {
VRInputAction vrinputaction = this.getInputAction(keyBinding);

if (vrinputaction.isEnabled() && vrinputaction.getLastOrigin() != 0L && vrinputaction.getAxis2D(true).getY() != 0.0F) {
float f = vrinputaction.getAxis2D(false).getY();

if (f > 0.0F) {
upCallback.run();
} else if (f < 0.0F) {
downCallback.run();
}
}
}

protected void processSwipeInput(KeyMapping keyBinding, Runnable leftCallback, Runnable rightCallback, Runnable upCallback, Runnable downCallback) {
VRInputAction vrinputaction = this.getInputAction(keyBinding);

if (vrinputaction.isEnabled() && vrinputaction.getLastOrigin() != 0L) {
ControllerType controllertype = this.findActiveBindingControllerType(keyBinding);

if (controllertype != null) {
if (!this.trackpadSwipeSamplers.containsKey(keyBinding.getName())) {
this.trackpadSwipeSamplers.put(keyBinding.getName(), new TrackpadSwipeSampler());
}

TrackpadSwipeSampler trackpadswipesampler = this.trackpadSwipeSamplers.get(keyBinding.getName());
trackpadswipesampler.update(controllertype, vrinputaction.getAxis2D(false));

if (trackpadswipesampler.isSwipedUp() && upCallback != null) {
this.triggerHapticPulse(controllertype, 0.001F, 400.0F, 0.5F);
upCallback.run();
}

if (trackpadswipesampler.isSwipedDown() && downCallback != null) {
this.triggerHapticPulse(controllertype, 0.001F, 400.0F, 0.5F);
downCallback.run();
}

if (trackpadswipesampler.isSwipedLeft() && leftCallback != null) {
this.triggerHapticPulse(controllertype, 0.001F, 400.0F, 0.5F);
leftCallback.run();
}

if (trackpadswipesampler.isSwipedRight() && rightCallback != null) {
this.triggerHapticPulse(controllertype, 0.001F, 400.0F, 0.5F);
rightCallback.run();
}
}
}
}

private void addActionParams(Map<String, ActionParams> map, KeyMapping keyBinding, String requirement, String type, VRInputActionSet actionSetOverride) {
ActionParams actionparams = new ActionParams(requirement, type, actionSetOverride);
map.put(keyBinding.getName(), actionparams);
Expand Down Expand Up @@ -1174,6 +1291,7 @@ private void addActionParams(Map<String, ActionParams> map, KeyMapping keyBindin

public abstract boolean isActive();

public abstract ControllerType getOriginControllerType(long i);
public boolean capFPS() {
return false;
}
Expand Down
Loading