forked from Clones/Controlify
✏️ Modify vmouse so that controls feel "less square" + apply a harsher easing function (quad -> cubic)
This commit is contained in:
@ -141,7 +141,7 @@ public class InGameInputHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var isAiming = isAiming(player);
|
boolean isAiming = isAiming(player);
|
||||||
|
|
||||||
float impulseY = 0f;
|
float impulseY = 0f;
|
||||||
float impulseX = 0f;
|
float impulseX = 0f;
|
||||||
@ -162,13 +162,13 @@ public class InGameInputHandler {
|
|||||||
}, 0, turnAngle));
|
}, 0, turnAngle));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// TODO: refactor this function majorly, so you can easily multiply the impulse vec's length
|
||||||
|
// possibly separate the flick stick code into its own function?
|
||||||
// normal look input
|
// normal look input
|
||||||
impulseY = controller.bindings().LOOK_DOWN.state() - controller.bindings().LOOK_UP.state();
|
impulseY = controller.bindings().LOOK_DOWN.state() - controller.bindings().LOOK_UP.state();
|
||||||
impulseX = controller.bindings().LOOK_RIGHT.state() - controller.bindings().LOOK_LEFT.state();
|
impulseX = controller.bindings().LOOK_RIGHT.state() - controller.bindings().LOOK_LEFT.state();
|
||||||
impulseX *= Math.abs(impulseX) * 10f; // 10 degrees per second
|
impulseX *= controller.config().horizontalLookSensitivity * 10f; // 10 degrees per second at 100% sensitivity
|
||||||
impulseY *= Math.abs(impulseY) * 10f;
|
impulseY *= controller.config().verticalLookSensitivity * 10f;
|
||||||
impulseX *= controller.config().horizontalLookSensitivity;
|
|
||||||
impulseY *= controller.config().verticalLookSensitivity;
|
|
||||||
|
|
||||||
if (controller.config().reduceAimingSensitivity && player.isUsingItem()) {
|
if (controller.config().reduceAimingSensitivity && player.isUsingItem()) {
|
||||||
float aimMultiplier = switch (player.getUseItem().getUseAnimation()) {
|
float aimMultiplier = switch (player.getUseItem().getUseAnimation()) {
|
||||||
|
@ -31,7 +31,7 @@ public abstract class AbstractContainerScreenMixin<T extends AbstractContainerMe
|
|||||||
@Override
|
@Override
|
||||||
public Set<SnapPoint> getSnapPoints() {
|
public Set<SnapPoint> getSnapPoints() {
|
||||||
return getMenu().slots.stream()
|
return getMenu().slots.stream()
|
||||||
.map(slot -> new SnapPoint(new Vector2i(leftPos + slot.x + 8, topPos + slot.y + 8), 14))
|
.map(slot -> new SnapPoint(new Vector2i(leftPos + slot.x + 8, topPos + slot.y + 8), 15))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,9 +6,11 @@ import dev.isxander.controlify.controller.gamepad.GamepadController;
|
|||||||
import dev.isxander.controlify.hid.ControllerHIDService;
|
import dev.isxander.controlify.hid.ControllerHIDService;
|
||||||
import dev.isxander.controlify.hid.HIDDevice;
|
import dev.isxander.controlify.hid.HIDDevice;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
|
import org.joml.Vector2f;
|
||||||
|
|
||||||
import java.util.HexFormat;
|
import java.util.HexFormat;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class ControllerUtils {
|
public class ControllerUtils {
|
||||||
public static String createControllerString(Controller<?, ?> controller) {
|
public static String createControllerString(Controller<?, ?> controller) {
|
||||||
@ -38,6 +40,16 @@ public class ControllerUtils {
|
|||||||
return (float) (y * Math.sqrt(1 - (x * x) / 2));
|
return (float) (y * Math.sqrt(1 - (x * x) / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Vector2f applyEasingToLength(float x, float y, Function<Float, Float> easing) {
|
||||||
|
float length = Mth.sqrt(x * x + y * y);
|
||||||
|
float easedLength = easing.apply(length);
|
||||||
|
float angle = (float) Mth.atan2(y, x);
|
||||||
|
return new Vector2f(
|
||||||
|
Mth.cos(angle) * easedLength,
|
||||||
|
Mth.sin(angle) * easedLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean shouldApplyAntiSnapBack(float x, float y, float px, float py, float threshold) {
|
public static boolean shouldApplyAntiSnapBack(float x, float y, float px, float py, float threshold) {
|
||||||
float dx = x - px;
|
float dx = x - px;
|
||||||
float dy = y - py;
|
float dy = y - py;
|
||||||
|
@ -14,6 +14,7 @@ import dev.isxander.controlify.screenop.ScreenProcessorProvider;
|
|||||||
import dev.isxander.controlify.api.event.ControlifyEvents;
|
import dev.isxander.controlify.api.event.ControlifyEvents;
|
||||||
import dev.isxander.controlify.mixins.feature.virtualmouse.KeyboardHandlerAccessor;
|
import dev.isxander.controlify.mixins.feature.virtualmouse.KeyboardHandlerAccessor;
|
||||||
import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor;
|
import dev.isxander.controlify.mixins.feature.virtualmouse.MouseHandlerAccessor;
|
||||||
|
import dev.isxander.controlify.utils.ControllerUtils;
|
||||||
import dev.isxander.controlify.utils.HoldRepeatHelper;
|
import dev.isxander.controlify.utils.HoldRepeatHelper;
|
||||||
import dev.isxander.controlify.utils.ToastUtils;
|
import dev.isxander.controlify.utils.ToastUtils;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
@ -23,14 +24,13 @@ import net.minecraft.client.gui.navigation.ScreenDirection;
|
|||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.Mth;
|
import net.minecraft.util.Mth;
|
||||||
import org.joml.RoundingMode;
|
import org.joml.*;
|
||||||
import org.joml.Vector2d;
|
|
||||||
import org.joml.Vector2dc;
|
|
||||||
import org.joml.Vector2i;
|
|
||||||
import org.lwjgl.glfw.GLFW;
|
import org.lwjgl.glfw.GLFW;
|
||||||
|
|
||||||
|
import java.lang.Math;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
public class VirtualMouseHandler {
|
public class VirtualMouseHandler {
|
||||||
private static final ResourceLocation CURSOR_TEXTURE = new ResourceLocation("controlify", "textures/gui/virtual_mouse.png");
|
private static final ResourceLocation CURSOR_TEXTURE = new ResourceLocation("controlify", "textures/gui/virtual_mouse.png");
|
||||||
@ -68,10 +68,19 @@ public class VirtualMouseHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var impulseY = controller.bindings().VMOUSE_MOVE_DOWN.state() - controller.bindings().VMOUSE_MOVE_UP.state();
|
|
||||||
var impulseX = controller.bindings().VMOUSE_MOVE_RIGHT.state() - controller.bindings().VMOUSE_MOVE_LEFT.state();
|
// apply an easing function directly to the vector's length
|
||||||
var prevImpulseY = controller.bindings().VMOUSE_MOVE_DOWN.prevState() - controller.bindings().VMOUSE_MOVE_UP.prevState();
|
// if you do easing(x), easing(y), then the diagonals where it's something like (~0.8, ~0.8) will incorrectly ease
|
||||||
var prevImpulseX = controller.bindings().VMOUSE_MOVE_RIGHT.prevState() - controller.bindings().VMOUSE_MOVE_LEFT.prevState();
|
Vector2f impulse = ControllerUtils.applyEasingToLength(
|
||||||
|
controller.bindings().VMOUSE_MOVE_RIGHT.state() - controller.bindings().VMOUSE_MOVE_LEFT.state(),
|
||||||
|
controller.bindings().VMOUSE_MOVE_DOWN.state() - controller.bindings().VMOUSE_MOVE_UP.state(),
|
||||||
|
x -> (float) Math.pow(x, 3)
|
||||||
|
);
|
||||||
|
Vector2f prevImpulse = ControllerUtils.applyEasingToLength(
|
||||||
|
controller.bindings().VMOUSE_MOVE_RIGHT.prevState() - controller.bindings().VMOUSE_MOVE_LEFT.prevState(),
|
||||||
|
controller.bindings().VMOUSE_MOVE_DOWN.prevState() - controller.bindings().VMOUSE_MOVE_UP.prevState(),
|
||||||
|
x -> (float) Math.pow(x, 3)
|
||||||
|
);
|
||||||
|
|
||||||
if (minecraft.screen != null && minecraft.screen instanceof ISnapBehaviour snapBehaviour) {
|
if (minecraft.screen != null && minecraft.screen instanceof ISnapBehaviour snapBehaviour) {
|
||||||
snapPoints = snapBehaviour.getSnapPoints();
|
snapPoints = snapBehaviour.getSnapPoints();
|
||||||
@ -80,18 +89,18 @@ public class VirtualMouseHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if just released stick, snap to nearest snap point
|
// if just released stick, snap to nearest snap point
|
||||||
if (impulseX == 0 && impulseY == 0) {
|
if (impulse.x == 0 && impulse.y == 0) {
|
||||||
if ((prevImpulseX != 0 || prevImpulseY != 0))
|
if ((prevImpulse.x != 0 || prevImpulse.y != 0))
|
||||||
snapToClosestPoint();
|
snapToClosestPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
var sensitivity = controller.config().virtualMouseSensitivity;
|
var sensitivity = controller.config().virtualMouseSensitivity;
|
||||||
var windowSizeModifier = Math.max(minecraft.getWindow().getWidth(), minecraft.getWindow().getHeight()) / 800f;
|
var windowSizeModifier = Math.max(minecraft.getWindow().getWidth(), minecraft.getWindow().getHeight()) / 800f;
|
||||||
|
|
||||||
// quadratic function to make small movements smaller
|
// cubic function to make small movements smaller
|
||||||
// abs to keep sign
|
// abs to keep sign
|
||||||
targetX += impulseX * Mth.abs(impulseX) * 20f * sensitivity * windowSizeModifier;
|
targetX += impulse.x * 20f * sensitivity * windowSizeModifier;
|
||||||
targetY += impulseY * Mth.abs(impulseY) * 20f * sensitivity * windowSizeModifier;
|
targetY += impulse.y * 20f * sensitivity * windowSizeModifier;
|
||||||
|
|
||||||
targetX = Mth.clamp(targetX, 0, minecraft.getWindow().getWidth());
|
targetX = Mth.clamp(targetX, 0, minecraft.getWindow().getWidth());
|
||||||
targetY = Mth.clamp(targetY, 0, minecraft.getWindow().getHeight());
|
targetY = Mth.clamp(targetY, 0, minecraft.getWindow().getHeight());
|
||||||
|
Reference in New Issue
Block a user