Skip to content

Commit

Permalink
Initial API
Browse files Browse the repository at this point in the history
  • Loading branch information
hammy275 committed Dec 21, 2024
1 parent e2ef36a commit fc4e468
Show file tree
Hide file tree
Showing 38 changed files with 1,349 additions and 231 deletions.
35 changes: 35 additions & 0 deletions common/src/main/java/org/vivecraft/api/VivecraftAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.vivecraft.api;

import net.minecraft.world.entity.player.Player;
import org.vivecraft.api.data.VRData;
import org.vivecraft.common.api_impl.APIImpl;

import javax.annotation.Nullable;

public interface VivecraftAPI {

/**
* @return The Vivecraft API instance for interacting with Vivecraft's API.
*/
static VivecraftAPI getInstance() {
return APIImpl.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 data 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 data of.
* @return The VR data for a player, or null if the player isn't in VR or no data has been received for said player.
*/
@Nullable
VRData getVRData(Player player);
}
64 changes: 64 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,64 @@
package org.vivecraft.api.client;

import net.minecraft.client.player.LocalPlayer;
import net.minecraft.world.entity.player.Player;

/**
* 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 VivecraftClientAPI#getPreTickWorldData()}, as this provides
* the most up-to-date data, and other methods such as {@link VivecraftClientAPI#getPostTickWorldData()} or
* {@link org.vivecraft.api.VivecraftAPI#getVRData(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 data for the local player. This is called whenever {@link #isActive(LocalPlayer)} returns false.
*
* @param player The local player, which will have their data reset.
*/
default void reset(LocalPlayer player) {

}

/**
* Called for all players, 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
}
}
212 changes: 212 additions & 0 deletions common/src/main/java/org/vivecraft/api/client/VivecraftClientAPI.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package org.vivecraft.api.client;

import com.google.common.annotations.Beta;
import net.minecraft.world.InteractionHand;
import org.vivecraft.api.client.data.VRPoseHistory;
import org.vivecraft.api.data.VRData;
import org.vivecraft.client.api_impl.ClientAPIImpl;
import org.vivecraft.client_vr.render.RenderPass;

import javax.annotation.Nullable;

public interface VivecraftClientAPI {

static VivecraftClientAPI getInstance() {
return ClientAPIImpl.INSTANCE;
}

/**
* Adds 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 addTracker(Tracker tracker);

/**
* Gets data representing the devices as they exist in the room before the game tick.
* Note that this data is gathered BEFORE mod loaders' pre-tick events.
*
* @return Data representing the devices in the room pre-tick, or null if the local player isn't in VR.
*/
@Nullable
VRData getPreTickRoomData();

/**
* Gets data representing the devices as they exist in the room after the game tick.
* Note that this data is gathered AFTER mod loaders' post-tick events.
*
* @return Data representing the devices in the room post-tick, or null if the local player isn't in VR.
*/
@Nullable
VRData getPostTickRoomData();

/**
* Gets data representing the devices as they exist in Minecraft coordinates before the game tick.
* This is the same as {@link #getPreTickRoomData()} with translation to Minecraft's coordinates as of the last
* tick, and is the main data source used by Vivecraft. If you're unsure which {@link VRData} method to use, you
* likely want to use this one.
* Note that this data is gathered BEFORE mod loaders' pre-tick events.
*
* @return Data representing the devices in Minecraft space pre-tick, or null if the local player isn't in VR.
*/
@Nullable
VRData getPreTickWorldData();

/**
* Gets data representing the devices as they exist in Minecraft coordinates after the game tick.
* This is the data sent to the server, and also used to calculate the data in {@link #getWorldRenderData()}.
* Note that this data is gathered AFTER mod loaders' post-tick events.
*
* @return Data representing the devices in Minecraft space post-tick, or null if the local player isn't in VR.
*/
@Nullable
VRData getPostTickWorldData();

/**
* Gets data representing the devices as they exist in Minecraft coordinates after the game tick interpolated for
* rendering.
* This is the same data as {@link #getPostTickWorldData()}, however it is interpolated for rendering.
*
* @return Data representing the devices in Minecraft space post-tick interpolated for rendering, or null if the
* local player isn't in VR.
*/
@Nullable
VRData getWorldRenderData();

/**
* 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 primary controller, while 1 is
* the secondary 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 primary controller, while 1 is
* the secondary 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 client player is currently in seated mode.
*/
boolean isSeated();

/**
* @return Whether the client player is using reversed hands.
*/
boolean usingReversedHands();

/**
* @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();

/**
* Returns the history of VR poses for the player for the HMD. Will return null if the player isn't
* in VR.
*
* @return The historical VR data for the player's HMD, or null if the player isn't in VR.
*/
@Nullable
VRPoseHistory getHistoricalVRHMDPoses();

/**
* Returns the history of VR poses for the player for a controller. Will return null if the player isn't
* in VR.
*
* @param controller The controller number to get, with 0 being the primary controller.
* @return The historical VR data for the player's controller, or null if the player isn't in VR.
*/
@Nullable
VRPoseHistory getHistoricalVRControllerPoses(int controller);

/**
* Returns the history of VR poses for the player for a controller. Will return null if the player isn't
* in VR.
*
* @param hand The hand to get controller history for.
* @return The historical VR data for the player's controller, or null if the player isn't in VR.
*/
@Nullable
default VRPoseHistory getHistoricalVRControllerPoses(InteractionHand hand) {
return getHistoricalVRControllerPoses(hand.ordinal());
}

/**
* Returns the history of VR poses for the player for the primary controller. Will return null if the
* player isn't in VR.
*
* @return The historical VR data for the player's primary controller, or null if the player isn't in VR.
*/
@Nullable
default VRPoseHistory getHistoricalVRController0Poses() {
return getHistoricalVRControllerPoses(0);
}

/**
* Returns the history of VR poses for the player for the secondary controller. Will return null if the
* player isn't in VR.
*
* @return The historical VR data for the player's secondary controller, or null if the player isn't in VR.
*/
@Nullable
default VRPoseHistory getHistoricalVRController1Poses() {
return getHistoricalVRControllerPoses(1);
}

/**
* 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);

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

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

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

0 comments on commit fc4e468

Please sign in to comment.