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;
|
||||
}
|
||||
|
||||
var isAiming = isAiming(player);
|
||||
boolean isAiming = isAiming(player);
|
||||
|
||||
float impulseY = 0f;
|
||||
float impulseX = 0f;
|
||||
@ -162,13 +162,13 @@ public class InGameInputHandler {
|
||||
}, 0, turnAngle));
|
||||
}
|
||||
} 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
|
||||
impulseY = controller.bindings().LOOK_DOWN.state() - controller.bindings().LOOK_UP.state();
|
||||
impulseX = controller.bindings().LOOK_RIGHT.state() - controller.bindings().LOOK_LEFT.state();
|
||||
impulseX *= Math.abs(impulseX) * 10f; // 10 degrees per second
|
||||
impulseY *= Math.abs(impulseY) * 10f;
|
||||
impulseX *= controller.config().horizontalLookSensitivity;
|
||||
impulseY *= controller.config().verticalLookSensitivity;
|
||||
impulseX *= controller.config().horizontalLookSensitivity * 10f; // 10 degrees per second at 100% sensitivity
|
||||
impulseY *= controller.config().verticalLookSensitivity * 10f;
|
||||
|
||||
if (controller.config().reduceAimingSensitivity && player.isUsingItem()) {
|
||||
float aimMultiplier = switch (player.getUseItem().getUseAnimation()) {
|
||||
|
@ -31,7 +31,7 @@ public abstract class AbstractContainerScreenMixin<T extends AbstractContainerMe
|
||||
@Override
|
||||
public Set<SnapPoint> getSnapPoints() {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
@ -6,9 +6,11 @@ import dev.isxander.controlify.controller.gamepad.GamepadController;
|
||||
import dev.isxander.controlify.hid.ControllerHIDService;
|
||||
import dev.isxander.controlify.hid.HIDDevice;
|
||||
import net.minecraft.util.Mth;
|
||||
import org.joml.Vector2f;
|
||||
|
||||
import java.util.HexFormat;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ControllerUtils {
|
||||
public static String createControllerString(Controller<?, ?> controller) {
|
||||
@ -38,6 +40,16 @@ public class ControllerUtils {
|
||||
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) {
|
||||
float dx = x - px;
|
||||
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.mixins.feature.virtualmouse.KeyboardHandlerAccessor;
|
||||
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.ToastUtils;
|
||||
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.resources.ResourceLocation;
|
||||
import net.minecraft.util.Mth;
|
||||
import org.joml.RoundingMode;
|
||||
import org.joml.Vector2d;
|
||||
import org.joml.Vector2dc;
|
||||
import org.joml.Vector2i;
|
||||
import org.joml.*;
|
||||
import org.lwjgl.glfw.GLFW;
|
||||
|
||||
import java.lang.Math;
|
||||
import java.util.Comparator;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class VirtualMouseHandler {
|
||||
private static final ResourceLocation CURSOR_TEXTURE = new ResourceLocation("controlify", "textures/gui/virtual_mouse.png");
|
||||
@ -68,10 +68,19 @@ public class VirtualMouseHandler {
|
||||
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();
|
||||
var prevImpulseY = controller.bindings().VMOUSE_MOVE_DOWN.prevState() - controller.bindings().VMOUSE_MOVE_UP.prevState();
|
||||
var prevImpulseX = controller.bindings().VMOUSE_MOVE_RIGHT.prevState() - controller.bindings().VMOUSE_MOVE_LEFT.prevState();
|
||||
|
||||
// apply an easing function directly to the vector's length
|
||||
// if you do easing(x), easing(y), then the diagonals where it's something like (~0.8, ~0.8) will incorrectly ease
|
||||
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) {
|
||||
snapPoints = snapBehaviour.getSnapPoints();
|
||||
@ -80,18 +89,18 @@ public class VirtualMouseHandler {
|
||||
}
|
||||
|
||||
// if just released stick, snap to nearest snap point
|
||||
if (impulseX == 0 && impulseY == 0) {
|
||||
if ((prevImpulseX != 0 || prevImpulseY != 0))
|
||||
if (impulse.x == 0 && impulse.y == 0) {
|
||||
if ((prevImpulse.x != 0 || prevImpulse.y != 0))
|
||||
snapToClosestPoint();
|
||||
}
|
||||
|
||||
var sensitivity = controller.config().virtualMouseSensitivity;
|
||||
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
|
||||
targetX += impulseX * Mth.abs(impulseX) * 20f * sensitivity * windowSizeModifier;
|
||||
targetY += impulseY * Mth.abs(impulseY) * 20f * sensitivity * windowSizeModifier;
|
||||
targetX += impulse.x * 20f * sensitivity * windowSizeModifier;
|
||||
targetY += impulse.y * 20f * sensitivity * windowSizeModifier;
|
||||
|
||||
targetX = Mth.clamp(targetX, 0, minecraft.getWindow().getWidth());
|
||||
targetY = Mth.clamp(targetY, 0, minecraft.getWindow().getHeight());
|
||||
|
Reference in New Issue
Block a user