Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.vmstudio.visor.api.client.input.redirect;

import org.vmstudio.visor.api.common.addon.VisorAddon;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation to register your {@link VRInputRedirect} automatically on addon load.
*
* <p>
* Class have to:<br>
* 1) Be a child of {@link VRInputRedirect} <br>
* 2) Contain constructor with a single parameter:
* {@link VisorAddon}
* </p>
*
* <p>
* To make it detectable by Visor, you need to implement
* {@link VisorAddon#getAddonPackagePath()}
* </p>
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface RegisterVRInputRedirect {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.vmstudio.visor.api.client.input.redirect;

import lombok.Getter;
import lombok.Setter;
import net.minecraft.client.player.LocalPlayer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.joml.Vector2fc;
import org.vmstudio.visor.api.client.input.InputHelper;
import org.vmstudio.visor.api.common.addon.VisorAddon;
import org.vmstudio.visor.api.common.addon.component.ComponentPriority;
import org.vmstudio.visor.api.common.addon.component.PrioritySupporter;
import org.vmstudio.visor.api.common.addon.component.VisorComponent;

/**
* Redirects VR movement input from joystick
* to methods in this component.
* <p>
* Useful, when you need to add compatibility with mods that
* use mouse move/scroll in-game without a Screen
* (e.g. Create Aeronautics levers, physics assembler)
* </p>
*/
public abstract class VRInputRedirect implements VisorComponent, PrioritySupporter {

@Getter
private final VisorAddon owner;

@Getter @Setter
private boolean enabled = true;

public VRInputRedirect(@NotNull VisorAddon owner) {
this.owner = owner;
}


/**
* If VR input can be redirected
*
* @param player the local player
* @return true/false
*/
public abstract boolean canRedirect(@NotNull LocalPlayer player);

/**
* The raw joystick state, delivered every VR pre-tick while the redirect is
* active.
*
* <p>
* Use it for anything that follows the stick continuously - a lever
* being pulled, a wheel being turned.
* </p>
*
* @param player the local player
* @param axis joystick position, x - right, y - forward, within [-1;1]
* @return true if the axis was used, which also skips
* {@link #onScroll(LocalPlayer, double, double)} for this tick
*/
public boolean onAxis(@NotNull LocalPlayer player,
@NotNull Vector2fc axis) {
return false;
}

/**
* Discrete scroll steps built up from the vertical joystick axis.
*
* @param player the local player
* @param deltaX horizontal steps
* @param deltaY vertical steps
*/
public void onScroll(@NotNull LocalPlayer player,
double deltaX,
double deltaY) {
}

/**
* Called once when the redirect stops being active.
*
* @param player the local player
*/
public void onStop(@Nullable LocalPlayer player) {

}


public final boolean isEnabledAndCanRedirect(@NotNull LocalPlayer player) {
return enabled && canRedirect(player);
}

@Override
public @NotNull ComponentPriority getPriority() {
return ComponentPriority.NORMAL;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import org.vmstudio.visor.api.client.gui.settings.VRSettingsPreset;
import org.vmstudio.visor.api.client.input.action.RegisterActionSet;
import org.vmstudio.visor.api.client.input.action.VRActionSet;
import org.vmstudio.visor.api.client.input.redirect.RegisterVRInputRedirect;
import org.vmstudio.visor.api.client.input.redirect.VRInputRedirect;
import org.vmstudio.visor.api.client.player.body.RegisterVRBodyType;
import org.vmstudio.visor.api.client.player.body.VRBodyType;
import org.vmstudio.visor.api.client.render.decoration.VRDecorator;
Expand Down Expand Up @@ -53,6 +55,18 @@ public interface ComponentRegistries {
ComponentRegistry<VRActionSet> actionSets();


/**
* Get VR input redirect registry
*
* <p>Annotation to auto-register on load: {@link RegisterVRInputRedirect}</p>
*
* @return VR Input redirect registry instance
*/
@NotNull
@Environment(EnvType.CLIENT)
ComponentRegistry<VRInputRedirect> inputRedirects();



/**
* Get VR Decorator registry
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.vmstudio.visor.compatibility.aeronautics;

import net.minecraft.client.player.LocalPlayer;
import org.jetbrains.annotations.NotNull;
import org.joml.Vector2fc;
import org.vmstudio.visor.api.client.input.redirect.VRInputRedirect;
import org.vmstudio.visor.api.common.addon.VisorAddon;
import org.vmstudio.visor.compatibility.aeronautics.internal.AeronauticsInputInternal;
import org.vmstudio.visor.compatibility.aeronautics.internal.AeronauticsStaffInternal;

public class AeroStaffVRInputRedirect extends VRInputRedirect {
private static final String ID = "aeronautics_staff";


private static final double ROTATE_DEGREES_PER_TICK = 4.0;

public AeroStaffVRInputRedirect(@NotNull VisorAddon owner) {
super(owner);
}


@Override
public boolean canRedirect(@NotNull LocalPlayer player) {
return player.isShiftKeyDown() && AeronauticsStaffInternal.isDragging();
}

@Override
public boolean onAxis(@NotNull LocalPlayer player,
@NotNull Vector2fc axis) {
if (axis.x() != 0) {
AeronauticsStaffInternal.rotateDragged(
Math.toRadians(axis.x() * ROTATE_DEGREES_PER_TICK)
);
}
//We need scroll steps for the distance, so,
// don't send true here to not cancel scroll method
return false;
}

@Override
public void onScroll(@NotNull LocalPlayer player,
double deltaX,
double deltaY) {
AeronauticsInputInternal.sendMouseScroll(deltaX, deltaY);
}

@Override
public @NotNull String getId() {
return ID;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.vmstudio.visor.compatibility.aeronautics;

import net.minecraft.client.player.LocalPlayer;
import org.jetbrains.annotations.NotNull;
import org.joml.Vector2fc;
import org.vmstudio.visor.api.client.input.redirect.VRInputRedirect;
import org.vmstudio.visor.api.common.addon.VisorAddon;
import org.vmstudio.visor.compatibility.aeronautics.internal.AeronauticsInputInternal;


public class AeroVRInputRedirect extends VRInputRedirect {
private static final String ID = "aeronautics";

public AeroVRInputRedirect(@NotNull VisorAddon owner) {
super(owner);
}


@Override
public boolean canRedirect(@NotNull LocalPlayer player) {
return AeronauticsInputInternal.isHoldInteractionActive();
}

@Override
public boolean onAxis(@NotNull LocalPlayer player,
@NotNull Vector2fc axis) {
if (axis.x() == 0 && axis.y() == 0) {
return false;
}
return AeronauticsInputInternal.sendMouseMove(
axis.x() * 60.0,
-axis.y() * 15.0
);
}

@Override
public void onScroll(@NotNull LocalPlayer player,
double deltaX,
double deltaY) {
AeronauticsInputInternal.sendMouseScroll(deltaX, deltaY);
}

@Override
public @NotNull String getId() {
return ID;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.vmstudio.visor.compatibility.aeronautics;

import org.jetbrains.annotations.NotNull;
import org.vmstudio.visor.api.ModLoader;
import org.vmstudio.visor.api.VisorAPI;
import org.vmstudio.visor.api.common.addon.VisorAddon;

public class AeronauticsHelper {
public static void initializeCompat(@NotNull VisorAddon owner) {
if (isLoaded()) {
var registries = VisorAPI.addonManager().getRegistries();

registries.itemPoses().registerComponent(new CreativeStaffItemPose(owner));
registries.inputRedirects().registerComponent(new AeroVRInputRedirect(owner));
registries.inputRedirects().registerComponent(new AeroStaffVRInputRedirect(owner));
}
}

public static boolean isLoaded() {
return ModLoader.get().isModLoaded("simulated");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.vmstudio.visor.compatibility.aeronautics;

import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Axis;
import net.minecraft.client.player.AbstractClientPlayer;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.joml.Quaternionf;
import org.vmstudio.visor.api.VisorAPI;
import org.vmstudio.visor.api.client.player.VRClientPlayer;
import org.vmstudio.visor.api.client.render.decoration.hand.VRHandItemPose;
import org.vmstudio.visor.api.common.HandType;
import org.vmstudio.visor.api.common.addon.VisorAddon;
import org.vmstudio.visor.api.common.addon.component.ComponentPriority;

public class CreativeStaffItemPose extends VRHandItemPose {
private static final String ID = "creative_staff_pose";

public CreativeStaffItemPose(@NotNull VisorAddon owner) { super(owner); }

@Override
public void applyPose(@NotNull PoseStack stack,
@NotNull AbstractClientPlayer player,
@NotNull HandType hand,
@NotNull ItemStack item,
float equipProgress,
float partialTicks) {
VRClientPlayer vrPlayer = VisorAPI.client().getVRPlayer(player.getUUID());
if (vrPlayer == null) return;

float scale = 1f;
float translateX = 0.0f;
float translateY = 0.4f;
float translateZ = -0.3f;
float yaw = -30f;
float pitch = 0f;
float roll = 0f;

Quaternionf rotation = new Quaternionf();
rotation.mul(Axis.ZP.rotationDegrees(roll));
rotation.mul(Axis.YP.rotationDegrees(pitch));
rotation.mul(Axis.XP.rotationDegrees(yaw));

stack.translate(translateX, translateY, translateZ);
stack.mulPose(rotation);
stack.scale(scale, scale, scale);
}

@Override
public boolean canApplyPose(@NotNull AbstractClientPlayer player,
@NotNull HandType hand,
@NotNull ItemStack itemStack) {
return itemStack.getItem().toString().equals("simulated:creative_physics_staff");
}

@Override
public @NotNull ComponentPriority getPriority() { return ComponentPriority.NORMAL; }

@Override
public @NotNull String getId() { return ID; }
}
Loading