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

[1.20.4] Many API Additions #255

Open
wants to merge 33 commits into
base: Multiloader-1.20.4
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a98752f
Initial API
hammy275 Aug 21, 2023
106fbcd
Fix Rebase Double-Tracker-Register Bug
hammy275 Jan 12, 2025
306dbf5
Left-Handed API Rename
hammy275 Jan 13, 2025
2803ff1
Rename API Impl Classes to Match API Classes
hammy275 Jan 13, 2025
848297b
VRPose and VRBodyPart Rename
hammy275 Jan 13, 2025
e0ab6de
Separate Vivecraft Rendering API Interface
hammy275 Jan 13, 2025
a542913
VR Capitalization Consistency
hammy275 Jan 13, 2025
562a193
Migrate History to VRPoseHistory
hammy275 Jan 13, 2025
4a5d9fc
FBT Additions (untested)
hammy275 Jan 13, 2025
c4d707e
Move averageSpeed() to Impl Class
hammy275 Jan 13, 2025
1524c4e
Hand Renaming and Docstring Changes
hammy275 Jan 13, 2025
31af70b
Vivecraft to VR Rename
hammy275 Jan 14, 2025
fe5aa1c
Translate Position for Player in Common API
hammy275 Jan 14, 2025
fab686c
Not VR Active Conditional for Default Return
hammy275 Jan 15, 2025
f43d9e3
Expose getControllerRenderPos and setupRenderingAtController in API
hammy275 Jan 15, 2025
d2da436
Just Expose Hands
hammy275 Jan 15, 2025
0f05591
Docstring Improvements
hammy275 Jan 16, 2025
5b781f2
Some Minor Adjustments
hammy275 Jan 16, 2025
50b9497
More Adjustments
hammy275 Jan 16, 2025
63fda6c
Remove Unused Method
hammy275 Jan 16, 2025
81a5a4b
More Fixing Up
hammy275 Jan 16, 2025
58c9d91
Adjust Names and Javadocs for Room Pose Client Methods
hammy275 Jan 16, 2025
be13825
Fix Undoing Refactor Changes
hammy275 Jan 16, 2025
45e8f42
VRPoseHistory Fixes
hammy275 Jan 16, 2025
dd8b95d
Merge VRBodyPart to One Enum
hammy275 Jan 17, 2025
428af8f
getInstance() --> instance() and Javadocs for a Couple
hammy275 Jan 20, 2025
5678cab
Refactor itemInUse() out to ItemInUseTracker
hammy275 Jan 21, 2025
3459c65
Make Not Default
hammy275 Jan 21, 2025
769b972
Cache VRPoses and Only Make VRPoseHistory When Needed
hammy275 Jan 26, 2025
2eb9047
Request Max Ticks of History Needed + Several VRPoseHistory Fixes
hammy275 Jan 26, 2025
e17fe8c
setTicksOfHistory --> requestTicksOfHistory
hammy275 Jan 26, 2025
b7b0fc3
One Set Method Instead of Two
hammy275 Jan 26, 2025
54d8e63
Javadoc Update
hammy275 Jan 31, 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
38 changes: 38 additions & 0 deletions common/src/main/java/org/vivecraft/api/VRAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package org.vivecraft.api;

import net.minecraft.world.entity.player.Player;
import org.vivecraft.api.data.VRPose;
import org.vivecraft.common.api_impl.VRAPIImpl;

import javax.annotation.Nullable;

/**
* The main interface for interacting with Vivecraft from common code.
*/
public interface VRAPI {

/**
* @return The Vivecraft API instance for interacting with Vivecraft's common API.
*/
static VRAPI instance() {
return VRAPIImpl.INSTANCE;
}

/**
* Check whether a given player is currently in VR.
*
* @param player The player to check the VR status of.
* @return true if the player is in VR.
*/
boolean isVRPlayer(Player player);

/**
* Returns the VR pose for the given player. Will return 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.
*
* @param player Player to get the VR pose of.
* @return The VR pose for a player, or null if the player isn't in VR or no data has been received for said player.
*/
@Nullable
VRPose getVRPose(Player player);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.vivecraft.api.client;

import net.minecraft.client.player.LocalPlayer;

/**
* An interface that should be implemented by {@link Tracker}s if they want to take advantage of
* {@link #itemInUse(LocalPlayer)}.
*/
public interface ItemInUseTracker {

/**
* Called for the client player, to check if this tracker is currently causing the item to be used to not release
* the use key. In other words, if you want the item currently being held to act as the use key being held, one
* should call the use item function, then return true from this method while the item should still remain used.
* @param player The local player which is running this tracker.
* @return Whether the item should remain in use.
*/
boolean itemInUse(LocalPlayer player);

}
65 changes: 65 additions & 0 deletions common/src/main/java/org/vivecraft/api/client/Tracker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package org.vivecraft.api.client;

import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.player.Player;
import org.vivecraft.api.VRAPI;

/**
* A tracker is an object that is run for the local player during the game tick or before rendering a frame only if
* they are in VR. Using trackers are one of the cleanest ways to interact with Vivecraft's data; it's how Vivecraft
* itself does. Trackers should generally use {@link VRClientAPI#getPreTickWorldPose()}, as this provides
* the most up-to-date data, and other methods such as {@link VRClientAPI#getPostTickWorldPose()} or
* {@link VRAPI#getVRPose(Player)} may not have data available when the tracker is run.
*/
public interface Tracker {

/**
* Whether the tracker is active for the local player.
*
* @param player Player being checked if they are active for this tracker instances.
* @return true if the tracker is active for the specified player.
*/
boolean isActive(LocalPlayer player);

/**
* Called for the client player if this tracker is active, which is when {@link #isActive(LocalPlayer)} returns true.
*
* @param player Player to run this tracker for, which is the local player.
*/
void doProcess(LocalPlayer player);

/**
* The ticking type for this tracker.
* If this is PER_FRAME, the tracker is called once with the local player per frame before the frame is rendered.
* If this is PER_TICK, the tracker is called once with the local player per game tick during the tick.
*
* @return The ticking type this tracker should use.
*/
TrackerTickType tickType();

/**
* Called to reset this tracker's state. This is called whenever {@link #isActive(LocalPlayer)} returns false.
*
* @param player The local player.
*/
default void reset(LocalPlayer player) {

}

/**
* Called for the local player, whether the tracker is active or not for them. This runs before
* {@link #isActive(LocalPlayer)} or {@link #reset(LocalPlayer)}.
*
* @param player Player to do an idle tick for, which is the local player.
*/
default void idleTick(LocalPlayer player) {

}

/**
* The timing type used for ticking trackers.
*/
enum TrackerTickType {
PER_FRAME, PER_TICK
}
}
164 changes: 164 additions & 0 deletions common/src/main/java/org/vivecraft/api/client/VRClientAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package org.vivecraft.api.client;

import org.vivecraft.api.client.data.VRPoseHistory;
import org.vivecraft.api.data.FBTMode;
import org.vivecraft.api.data.VRPose;
import org.vivecraft.client.api_impl.VRClientAPIImpl;

import javax.annotation.Nullable;

/**
* The main interface for interacting with Vivecraft from client code. For rendering, one should use
* {@link VRRenderingAPI}.
*/
public interface VRClientAPI {

/**
* @return The Vivecraft API instance for interacting with Vivecraft's client API.
*/
static VRClientAPI instance() {
return VRClientAPIImpl.INSTANCE;
}

/**
* Registers the tracker to the list of all trackers to be run for the local player. See the documentation for
* {@link Tracker} for more information on what a tracker is.
*
* @param tracker Tracker to register.
*/
void registerTracker(Tracker tracker);

/**
* Gets the VR pose representing the player in the room after the most recent poll of VR hardware.
*
* @return The most up-to-date VR pose representing the player in the room, or null if the local player isn't in VR.
*/
@Nullable
VRPose getLatestRoomPose();

/**
* Gets the VR pose representing the player in the room after the game tick.
* Note that this pose is gathered AFTER mod loaders' post-tick events.
*
* @return The VR pose representing the player in the room post-tick, or null if the local player isn't in VR.
*/
@Nullable
VRPose getPostTickRoomPose();

/**
* Gets the VR pose representing the player in Minecraft world coordinates before the game tick. If you're unsure
* which {@link VRPose} method to use, you very likely want to use this one.
* Note that this pose is gathered BEFORE mod loaders' pre-tick events.
*
* @return The VR pose representing the player in world space pre-tick, or null if the local player isn't in VR.
*/
@Nullable
VRPose getPreTickWorldPose();

/**
* Gets the VR pose representing the player in Minecraft world coordinates after the game tick.
* This is the pose sent to the server, and also used to calculate the pose in {@link #getWorldRenderPose()}.
* Note that this pose is gathered AFTER mod loaders' post-tick events.
*
* @return The VR pose representing the player in Minecraft space post-tick, or null if the local player isn't in VR.
*/
@Nullable
VRPose getPostTickWorldPose();

/**
* Gets the VR pose representing the player in Minecraft world coordinates interpolated for rendering.
*
* @return The VR pose representing the player in Minecraft space post-tick interpolated for rendering, or null if
* the local player isn't in VR.
*/
@Nullable
VRPose getWorldRenderPose();

/**
* Causes a haptic pulse (vibration/rumble) for the specified controller.
* This function silently fails if called for players not in VR or players who are in seated mode.
*
* @param controllerNum The controller number to trigger a haptic pulse. 0 is the main-hand's controller, while 1 is
* the off-hand's controller.
* @param duration The duration of the haptic pulse in seconds. Note that this number is passed to the
* underlying VR API used by Vivecraft, and may act with a shorter length than expected beyond
* very short pulses.
* @param frequency The frequency of the haptic pulse in Hz. 160 is a safe bet for this number, with Vivecraft's codebase
* using anywhere from 160F for actions such as a bite on a fishing line, to 1000F for things such
* as a chat notification.
* @param amplitude The amplitude of the haptic pulse. This should be kept between 0F and 1F.
* @param delay An amount of time to delay until creating the haptic pulse. The majority of the time, one should use 0F here.
*/
void triggerHapticPulse(int controllerNum, float duration, float frequency, float amplitude, float delay);

/**
* Causes a haptic pulse (vibration/rumble) for the specified controller.
* This function silently fails if called for players not in VR or players who are in seated mode.
*
* @param controllerNum The controller number to trigger a haptic pulse. 0 is the main-hand's controller, while 1 is
* the off-hand's controller.
* @param duration The duration of the haptic pulse in seconds. Note that this number is passed to the
* underlying VR API used by Vivecraft, and may act with a shorter length than expected beyond
* very short pulses.
*/
default void triggerHapticPulse(int controllerNum, float duration) {
triggerHapticPulse(controllerNum, duration, 160F, 1F, 0F);
}

/**
* @return Whether the local player is currently in seated mode.
*/
boolean isSeated();

/**
* @return Whether the local player is playing with left-handed controls.
*/
boolean isLeftHanded();

/**
* @return The full-body tracking mode currently in-use or some default value if the local player is not in VR.
*/
FBTMode getFBTMode();

/**
* @return Whether VR support is initialized.
*/
boolean isVRInitialized();

/**
* @return Whether the client is actively in VR.
*/
boolean isVRActive();

/**
* @return The currently active world scale.
*/
float getWorldScale();

/**
* Requests the amount of ticks of history wanted for {@link #getHistoricalVRPoses()}. Any value larger than 200
* will be capped at 200.
* @param maxTicksBack The maximum number of ticks of history wanted.
* @throws IllegalArgumentException If a non-positive number is supplied.
*/
void requestTicksOfHistory(int maxTicksBack) throws IllegalArgumentException;

/**
* Returns the history of VR poses for the player. One should make one call to {@link #requestTicksOfHistory(int)}
* before calling this method to inform Vivecraft of the amount of history to keep.
*
* @return The history of VR poses for the player. Will be null if the player isn't in VR or if
* {@link #requestTicksOfHistory(int)} has yet to be called.
*/
@Nullable
VRPoseHistory getHistoricalVRPoses();

/**
* Opens or closes Vivecraft's keyboard. Will fail silently if the user isn't in VR or if the keyboard's new state
* is the same as the old.
*
* @param isNowOpen Whether the keyboard should now be open. If false, the keyboard will attempt to close.
* @return Whether the keyboard is currently showing after attempting to open/close it.
*/
boolean setKeyboardState(boolean isNowOpen);
}
56 changes: 56 additions & 0 deletions common/src/main/java/org/vivecraft/api/client/VRRenderingAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.vivecraft.api.client;

import com.google.common.annotations.Beta;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.phys.Vec3;
import org.vivecraft.client.api_impl.VRRenderingAPIImpl;
import org.vivecraft.client_vr.render.RenderPass;

/**
* The main interface for interacting with Vivecraft from rendering code. For other client-side code, one should use
* {@link VRClientAPI}.
*/
public interface VRRenderingAPI {

/**
* @return The Vivecraft API instance for interacting with Vivecraft's rendering API.
*/
static VRRenderingAPI instance() {
return VRRenderingAPIImpl.INSTANCE;
}

/**
* @return Whether the current render pass is a vanilla render pass.
*/
boolean isVanillaRenderPass();

/**
* @return The current render pass Vivecraft is performing.
*/
RenderPass getCurrentRenderPass();

/**
* @return Whether the current render pass is the first one performed for this render cycle.
*/
boolean isFirstRenderPass();

/**
* Gets the position that the provided {@link InteractionHand} renders at. Unlike
* {@link org.vivecraft.api.data.VRPose#getHand(InteractionHand)} from {@link VRClientAPI#getWorldRenderPose()},
* this returns a reasonable, default value for seated mode.
* @param hand The hand to get the rendering position of.
* @return The rendering position for the provided hand.
*/
@Beta
Vec3 getHandRenderPos(InteractionHand hand);

/**
* Sets the provided {@link PoseStack} to render at the position of and with the rotation of the provided
* {@link InteractionHand}.
* @param hand The hand to set the PoseStack to.
* @param stack The PoseStack to be set.
*/
@Beta
void setupRenderingAtHand(InteractionHand hand, PoseStack stack);
}
Loading