Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
56cbd57
[WIP] Add openXR support (#230)
ferriarnus Aug 1, 2024
d51fea3
add subactionPaths and XR_SWAPCHAIN_CREATE_STATIC_IMAGE_BIT
ferriarnus Nov 1, 2024
2b97efb
test oculus openxr env
ferriarnus Nov 19, 2024
344dbb7
now for real, not with steamVR as default...
ferriarnus Nov 19, 2024
9996980
fix lwjgl openxr version
fayer3 Nov 21, 2024
5aa3faa
Merge remote-tracking branch 'remotes/origin/Multiloader-1.20.4' into…
fayer3 Nov 22, 2024
f09afdd
Fix Conformance Issues (#315)
CADIndie Nov 23, 2024
68d7d90
Create DeviceCompat for QuestCraft (#317)
CADIndie Nov 24, 2024
55aaad9
Merge remote-tracking branch 'remotes/origin/Multiloader-1.20.4' into…
fayer3 Nov 24, 2024
d4b5001
Merge branch 'Multiloader-1.20.4' into openxr
ferriarnus Dec 3, 2024
c154b9d
update after cleanup
ferriarnus Dec 3, 2024
1c77f7b
Merge branch 'Multiloader-1.20.4' into openxr
ferriarnus Dec 4, 2024
7264eed
update + cleanup
ferriarnus Dec 5, 2024
faa5263
fix eye position
ferriarnus Dec 5, 2024
d765122
fix openxr head rotation
fayer3 Dec 10, 2024
c8f298b
fix nullvr eye offset after last change
fayer3 Dec 11, 2024
8c95d05
fix lwjgl dependency declaration, parchment mappings and mixin extras
fayer3 Dec 16, 2024
1ede10d
fix fabric build gradle
fayer3 Dec 23, 2024
cbbe2c4
Merge branch 'openxr' into Multiloader-1.21.4
CADIndie Jan 7, 2025
c934837
Fixes and temp changes
CADIndie Jan 8, 2025
9f1099b
Merge pull request #338 from CADIndie/1.21.4-OpenXR
fayer3 Jan 8, 2025
b73f89f
some formatting, and cleanup
fayer3 Jan 8, 2025
d6205e0
fix binding origin name getting
fayer3 Jan 8, 2025
1a8ea30
change mirror to use framebuffer blits and openvr/nullvr fixes
fayer3 Jan 8, 2025
ad9099b
Merge remote-tracking branch 'remotes/origin/Multiloader-1.21.4' into…
fayer3 Jan 8, 2025
054fb74
handle VR events regardless of active state
fayer3 Jan 8, 2025
b54e705
fix inputs with openvr
fayer3 Jan 8, 2025
ab612fc
projection matrix only once per frame
fayer3 Jan 8, 2025
3a71a9e
fix analog button input
fayer3 Jan 8, 2025
48023e9
add interact/climbey bindings, fix cosoms bindings
fayer3 Jan 8, 2025
6c3a95b
Add Default, Pico, and Index Controller Bindings
CADIndie Jan 28, 2025
a87509b
Totally didn't forget the extension
CADIndie Jan 28, 2025
d61dd16
Merge pull request #348 from CADIndie/Bindings
fayer3 Jan 28, 2025
db061c1
Set Refresh Rate
CADIndie Jan 28, 2025
248facb
Ensure FBRefreshRate Before Usage
CADIndie Feb 15, 2025
beabae1
Merge pull request #349 from CADIndie/Refresh-Rate
fayer3 Feb 15, 2025
49d7a24
formatting
fayer3 Oct 6, 2025
4695fdf
fox sodium compat pre 0.4.9
fayer3 Oct 7, 2025
1df650a
fix crash with some mods, that don't expect the hitresult to be null
fayer3 Oct 7, 2025
2a4fbbd
bump to 1.3.2
fayer3 Oct 7, 2025
de05f5f
allow running on 1.21.10
fayer3 Oct 7, 2025
6393a66
clarify that disabling teleporting only works on 1.3.0+
fayer3 Oct 12, 2025
5ea0a38
change network version to an enum
fayer3 Oct 13, 2025
24f98d4
add option to disable mirror off text, and make it translateable
fayer3 Oct 13, 2025
44a9106
fix garbagecollector screens stacking when toggling vr on that screen
fayer3 Oct 13, 2025
d637722
fix hand rendering with shaders
fayer3 Oct 17, 2025
1e1f671
add waist freemove direction
fayer3 Oct 18, 2025
71ea12c
Player-Relative Pose History and Index Out of Bounds Fix (#405)
hammy275 Oct 18, 2025
2a79b0b
build against 1.21.10
fayer3 Oct 18, 2025
af73732
clarify some API javadoc
fayer3 Oct 19, 2025
3d0988a
fix file extraction on neoforge, and bump min neoforge version
fayer3 Oct 19, 2025
5b901d3
formatting
fayer3 Oct 19, 2025
50eb289
fix player not rendering when sleeping and instead showing up in VR
fayer3 Oct 20, 2025
d74dd24
bump to 1.3.3
fayer3 Oct 20, 2025
110358b
missing this
fayer3 Oct 20, 2025
38fbc32
fix crash with MCA on 1.21.1
fayer3 Oct 24, 2025
d7cadd9
fix ALLOW_ATTACKS_WHILE_BLOCKING server setting not working without c…
fayer3 Oct 24, 2025
6e7a0eb
fix broken projection matrix when some mod tries to set the far plane…
fayer3 Oct 25, 2025
b725b6e
fix attack while blocking packet not being handled at all
fayer3 Oct 25, 2025
e35e2e7
fix copy/cut/paste keys not working on the VR keyboard
fayer3 Oct 25, 2025
f60523e
fix broken menu panorama with the dirtbox menu
fayer3 Oct 26, 2025
2c5178d
fix crash when clearing the search and clicking a setting
fayer3 Oct 31, 2025
659ada9
another crash fix when removing entries from a list
fayer3 Oct 31, 2025
3afb126
fix crash neoforge 21.10.24+, and bump min version to that
fayer3 Nov 2, 2025
2b8b52a
fix optifine shaders
fayer3 Nov 2, 2025
4da75ab
update forge requirement, to block forge versions that break mixin ex…
fayer3 Nov 3, 2025
26df48f
move optifine cloud mixin to shaders mixin
fayer3 Nov 3, 2025
609415a
add keyboard layout editor and theme editor, and some keyboard layout…
fayer3 Nov 3, 2025
0cabbdb
bump to 1.3.4
fayer3 Nov 3, 2025
a5fcea8
add option to overlay the gui on the mirror.
fayer3 Nov 11, 2025
1cf8384
fix crash when opening the quick commands gui in nonvr
fayer3 Nov 12, 2025
c7e2b32
- allow smooth rotation to be activated with keybinds
fayer3 Nov 15, 2025
bb337c7
fix some menuworlds fail to load with serene season
fayer3 Nov 15, 2025
f7556e4
use fbt feet position for the player when available
fayer3 Nov 16, 2025
7e879dd
fix search button being offscreen on narrow windows sizes
fayer3 Nov 16, 2025
e10658e
Start working on Rebinding of keys (#412)
ferriarnus Nov 16, 2025
6d8d046
Merge remote-tracking branch 'remotes/origin/Multiloader-1.21.9' into…
fayer3 Nov 16, 2025
b1b1f5e
fixes for 1.21.10 and update
fayer3 Nov 16, 2025
51caad7
fix lang keys
fayer3 Nov 16, 2025
9fb821c
formatting
fayer3 Nov 16, 2025
3d06876
small cleanup
ferriarnus Nov 18, 2025
53276c4
split input actions
ferriarnus Nov 19, 2025
ec5d9f2
fix multibinds and origins
ferriarnus Nov 22, 2025
b463bba
re-enable other controllers
ferriarnus Nov 22, 2025
2599010
add steam names to ActionType for the manifest
ferriarnus Nov 23, 2025
9910652
formatting
fayer3 Nov 23, 2025
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
20 changes: 12 additions & 8 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,8 @@ subprojects {
dependencies {
minecraft "com.mojang:minecraft:${rootProject.minecraft_version}"
mappings loom.layered() {
// The following line declares the mojmap mappings, you may use other mappings as well
// The following line declares the mojmap mappings
officialMojangMappings()
// The following line declares the yarn mappings you may select this one as well.
// "net.fabricmc:yarn:1.18.2+build.4:v2"
// parchment mappings as backup
parchment("org.parchmentmc.data:parchment-${rootProject.parchment_version}@zip")
}
Expand All @@ -34,6 +32,13 @@ subprojects {
implementation("org.lwjgl:lwjgl-openvr:${rootProject.lwjgl_version}:natives-macos") { transitive = false }
implementation("org.lwjgl:lwjgl-openvr:${rootProject.lwjgl_version}:natives-windows") { transitive = false }

// Use custom OpenXR lib for Android and GLES bindings
//implementation("QuestCraftPlusPlus:lwjgl3:${rootProject.lwjgl_version}:lwjgl-openxr-${rootProject.lwjgl_version}")

implementation("org.lwjgl:lwjgl-openxr:${rootProject.lwjgl_version}")
implementation("org.lwjgl:lwjgl-openxr:${rootProject.lwjgl_version}:natives-linux")
implementation("org.lwjgl:lwjgl-openxr:${rootProject.lwjgl_version}:natives-windows")

// for OSC tracker support
implementation("com.illposed.osc:javaosc-core:0.9")

Expand Down Expand Up @@ -186,17 +191,16 @@ allprojects {
exclusiveContent {
forRepository {
ivy {
name = "Discord"
url = "https://cdn.discordapp.com/attachments/"
name = "GitHub"
url = "https://github.com/"
patternLayout {
artifact '/[organisation]/[module]/[revision].[ext]'
artifact '/[organisation]/[module]/releases/download/[revision]/[classifier].jar'
}
metadataSources { artifact() }
}
}
filter {
// discords are always just numbers
includeGroupByRegex "^\\d*\$"

}
}
}
Expand Down
2 changes: 1 addition & 1 deletion common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ dependencies {
compileOnly('com.electronwill.night-config:toml:3.6.6')

//LaunchPopup
implementation 'com.github.Vivecraft:LaunchPopup:1.1.1'
implementation 'Vivecraft:LaunchPopup:1.1.1:LaunchPopup-1.1.1'
}
// extract the LaunchPopup classes
jar {
Expand Down
15 changes: 13 additions & 2 deletions common/src/main/java/org/vivecraft/Xloader.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@

import dev.architectury.injectables.annotations.ExpectPlatform;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.util.List;

/**
* Xplat for stuff that only references modloader classes
Expand Down Expand Up @@ -66,10 +69,18 @@ static Path getConfigPath(String file) {
}

/**
* @return path to access files inside the mod jar
* @return InputStream corresponding to the given filepath inside the mod jar
*/
@ExpectPlatform
static Path getJarPath() {
static InputStream getInJarFile(String sourcePath) throws IOException {
throw new AssertionError();
}

/**
* @return List of all files in the given folder inside the mod jar
*/
@ExpectPlatform
static List<Path> getInJarFolderFiles(String folder) throws IOException {
throw new AssertionError();
}

Expand Down
3 changes: 2 additions & 1 deletion common/src/main/java/org/vivecraft/api/VRAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ static VRAPI instance() {

/**
* Returns the VR pose for the given player. Will return {@code null} if the player isn't in VR,
* or if being called from the client and the client has yet to receive any data for the player.
* or if no data for the player has been received yet. The VRPose can still be {@code null} if
* {@link VRAPI#isVRPlayer(Player)} returned true, since those two properties are independent of each other.
*
* @param player Player to get the VR pose of.
* @return The VR pose for a player, or {@code null} if the player isn't in VR or no data has been received for said player.
Expand Down
120 changes: 107 additions & 13 deletions common/src/main/java/org/vivecraft/api/data/VRPoseHistory.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@
* <br>
* Vivecraft will store data for players going up to 200 ticks into the past. Attempting to retrieve history before
* this far back will throw an {@link IllegalArgumentException}.
* <br>
* Many methods in this class accept the parameter {@code playerPositionRelative}. When this is {@code true}, all
* calculations are done relative to the player, while if {@code false}, calculations are done in world space. For
* example, the net movement of a player who moved from (0, 0, 0) to (3, 0, 0) but did NOT move their head, hands, etc.
* would be (3, 0, 0) if {@code playerPositionRelative} is {@code false} and would be (0, 0, 0) if
* {@code playerPositionRelative} is {@code true}.
*
* @since 1.3.0
*/
Expand All @@ -35,18 +41,31 @@ public interface VRPoseHistory {
List<VRPose> getAllHistoricalData();

/**
* Gets the pose from {@code ticksBack} ticks back, or {@code null} if such data isn't available.
* Gets the pose from {@code ticksBack} ticks back in world space, or {@code null} if such data isn't available.
*
* @param ticksBack Ticks back to retrieve data from.
* @return A {@link VRPose} instance from {@code ticksBack} ticks ago, or {@code null} if that data isn't available.
* @throws IllegalArgumentException Thrown when {@code ticksBack} is outside the range [0,200].
* @since 1.3.0
*/
VRPose getHistoricalData(int ticksBack) throws IllegalArgumentException;
default VRPose getHistoricalData(int ticksBack) throws IllegalArgumentException {
return getHistoricalData(ticksBack, false);
}

/**
* Gets the net movement between the most recent VRPose in this instance and the oldest VRPose that can be
* retrieved, going no farther back than {@code maxTicksBack}.
* Gets the pose from {@code ticksBack} ticks back, or {@code null} if such data isn't available.
*
* @param ticksBack Ticks back to retrieve data from.
* @param playerPositionRelative Whether to get the historical data with position relative to the player's position.
* @return A {@link VRPose} instance from {@code ticksBack} ticks ago, or {@code null} if that data isn't available.
* @throws IllegalArgumentException Thrown when {@code ticksBack} is outside the range [0,200].
* @since 1.3.3
*/
VRPose getHistoricalData(int ticksBack, boolean playerPositionRelative) throws IllegalArgumentException;

/**
* Gets the net movement in world space between the most recent VRPose in this instance and the oldest VRPose that
* can be retrieved, going no farther back than {@code maxTicksBack}.
*
* @param bodyPart The body part to get the net movement for.
* @param maxTicksBack The maximum number of ticks back to compare the most recent data with.
Expand All @@ -57,11 +76,30 @@ public interface VRPoseHistory {
* @since 1.3.0
*/
@Nullable
Vec3 netMovement(VRBodyPart bodyPart, int maxTicksBack) throws IllegalArgumentException;
default Vec3 netMovement(VRBodyPart bodyPart, int maxTicksBack) throws IllegalArgumentException {
return netMovement(bodyPart, maxTicksBack, false);
}

/**
* Gets the average velocity in blocks/tick between the most recent VRPose in this instance and the oldest VRPose
* that can be retrieved, going no farther back than {@code maxTicksBack}.
* Gets the net movement between the most recent VRPose in this instance and the oldest VRPose that can be
* retrieved, going no farther back than {@code maxTicksBack}.
*
* @param bodyPart The body part to get the net movement for.
* @param maxTicksBack The maximum number of ticks back to compare the most recent data with.
* @param playerPositionRelative Whether net movement should be calculated relative to the player position.
* @return The aforementioned net movement. Note that this will return zero change on all axes if only zero ticks
* can be looked back. Will be {@code null} if the body part requested isn't available.
* @throws IllegalArgumentException Thrown when {@code maxTicksBack} is outside the range [0,200] or an invalid
* {@code bodyPart} is supplied.
* @since 1.3.3
*/
@Nullable
Vec3 netMovement(
VRBodyPart bodyPart, int maxTicksBack, boolean playerPositionRelative) throws IllegalArgumentException;

/**
* Gets the average velocity in world space in blocks/tick between the most recent VRPose in this instance and the
* oldest VRPose that can be retrieved, going no farther back than {@code maxTicksBack}.
*
* @param bodyPart The body part to get the average velocity for.
* @param maxTicksBack The maximum number of ticks back to calculate velocity with.
Expand All @@ -72,12 +110,31 @@ public interface VRPoseHistory {
* @since 1.3.0
*/
@Nullable
Vec3 averageVelocity(VRBodyPart bodyPart, int maxTicksBack) throws IllegalArgumentException;
default Vec3 averageVelocity(VRBodyPart bodyPart, int maxTicksBack) throws IllegalArgumentException {
return averageVelocity(bodyPart, maxTicksBack, false);
}

/**
* Gets the average speed in blocks/tick between the most recent VRPose in this instance and the oldest VRPose
* Gets the average velocity in blocks/tick between the most recent VRPose in this instance and the oldest VRPose
* that can be retrieved, going no farther back than {@code maxTicksBack}.
*
* @param bodyPart The body part to get the average velocity for.
* @param maxTicksBack The maximum number of ticks back to calculate velocity with.
* @param playerPositionRelative Whether velocity should be calculated to the player position.
* @return The aforementioned average velocity on each axis. Note that this will return zero velocity on all axes
* if only zero ticks can be looked back. Will be {@code null} if the body part requested isn't available.
* @throws IllegalArgumentException Thrown when {@code maxTicksBack} is outside the range [0,200] or an invalid
* {@code bodyPart} is supplied.
* @since 1.3.3
*/
@Nullable
Vec3 averageVelocity(
VRBodyPart bodyPart, int maxTicksBack, boolean playerPositionRelative) throws IllegalArgumentException;

/**
* Gets the average speed in world space in blocks/tick between the most recent VRPose in this instance and the
* oldest VRPose that can be retrieved, going no farther back than {@code maxTicksBack}.
*
* @param bodyPart The body part to get the average speed for.
* @param maxTicksBack The maximum number of ticks back to calculate speed with.
* @return The aforementioned average speed on each axis. Note that this will return zero speed if only zero ticks
Expand All @@ -86,11 +143,29 @@ public interface VRPoseHistory {
* {@code bodyPart} is supplied.
* @since 1.3.0
*/
double averageSpeed(VRBodyPart bodyPart, int maxTicksBack) throws IllegalArgumentException;
default double averageSpeed(VRBodyPart bodyPart, int maxTicksBack) throws IllegalArgumentException {
return averageSpeed(bodyPart, maxTicksBack, false);
}

/**
* Gets the average position between the most recent VRPose in this instance and the oldest VRPose that can be
* retrieved, going no farther back than {@code maxTicksBack}.
* Gets the average speed in blocks/tick between the most recent VRPose in this instance and the oldest VRPose
* that can be retrieved, going no farther back than {@code maxTicksBack}.
*
* @param bodyPart The body part to get the average speed for.
* @param maxTicksBack The maximum number of ticks back to calculate speed with.
* @param playerPositionRelative Whether the speed should be calculated relative to the player position.
* @return The aforementioned average speed on each axis. Note that this will return zero speed if only zero ticks
* can be looked back, or if the body part requested isn't available.
* @throws IllegalArgumentException Thrown when {@code maxTicksBack} is outside the range [0,200] or an invalid
* {@code bodyPart} is supplied.
* @since 1.3.3
*/
double averageSpeed(
VRBodyPart bodyPart, int maxTicksBack, boolean playerPositionRelative) throws IllegalArgumentException;

/**
* Gets the average position in world space between the most recent VRPose in this instance and the oldest VRPose
* that can be retrieved, going no farther back than {@code maxTicksBack}.
*
* @param bodyPart The body part to get the average position for.
* @param maxTicksBack The maximum number of ticks back to calculate the position with.
Expand All @@ -101,5 +176,24 @@ public interface VRPoseHistory {
* @since 1.3.0
*/
@Nullable
Vec3 averagePosition(VRBodyPart bodyPart, int maxTicksBack) throws IllegalArgumentException;
default Vec3 averagePosition(VRBodyPart bodyPart, int maxTicksBack) throws IllegalArgumentException {
return averagePosition(bodyPart, maxTicksBack, false);
}

/**
* Gets the average position between the most recent VRPose in this instance and the oldest VRPose that can be
* retrieved, going no farther back than {@code maxTicksBack}.
*
* @param bodyPart The body part to get the average position for.
* @param maxTicksBack The maximum number of ticks back to calculate the position with.
* @param playerPositionRelative Whether the positions should be relative to the player's position.
* @return The aforementioned average position. Note that this will return the current position if only zero ticks
* can be looked back. Will be {@code null} if the body part requested isn't available.
* @throws IllegalArgumentException Thrown when {@code maxTicksBack} is outside the range [0,200] or an invalid
* {@code bodyPart} is supplied.
* @since 1.3.3
*/
@Nullable
Vec3 averagePosition(
VRBodyPart bodyPart, int maxTicksBack, boolean playerPositionRelative) throws IllegalArgumentException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,8 @@ public void update(
if (!localPlayer) {
Player otherPlayer = this.mc.level.getPlayerByUUID(uuid);
if (otherPlayer != null) {
VRAPIImpl.INSTANCE.addPoseToHistory(uuid, rotInfo.asVRPose(otherPlayer.position()), true);
VRAPIImpl.INSTANCE.addPoseToHistory(uuid, rotInfo.asVRPose(otherPlayer.position()),
otherPlayer.position(), true);
}
}

Expand Down
7 changes: 5 additions & 2 deletions common/src/main/java/org/vivecraft/client/VivecraftVRMod.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
import net.minecraft.resources.ResourceLocation;
import org.apache.commons.lang3.ArrayUtils;
import org.vivecraft.client_vr.gameplay.screenhandlers.GuiHandler;
import org.vivecraft.client_vr.provider.HandedKeyBinding;
import org.vivecraft.client_vr.provider.control.HandedKeyBinding;

import java.util.*;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Set;

public class VivecraftVRMod {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.vivecraft.client.api_impl;

import net.minecraft.world.phys.Vec3;
import org.vivecraft.api.client.VRClientAPI;
import org.vivecraft.api.client.data.CloseKeyboardContext;
import org.vivecraft.api.client.data.OpenKeyboardContext;
Expand Down Expand Up @@ -34,8 +35,8 @@ public void clearPoseHistory() {
this.poseHistory.clear();
}

public void addPoseToHistory(VRPose pose) {
this.poseHistory.addPose(pose);
public void addPoseToHistory(VRPose pose, Vec3 playerPos) {
this.poseHistory.addPose(pose, playerPos);
}

public void processRegistrationEvent() {
Expand Down
Loading