From dc78eb61a23d9d4e5ba4de5aad70840d77a68bdd Mon Sep 17 00:00:00 2001 From: isXander Date: Thu, 15 Jun 2023 18:34:28 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=8F=EF=B8=8F=20Real-world=20gyro=20sensit?= =?UTF-8?q?ivity?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/gamepad/GamepadConfig.java | 2 +- .../controller/gamepad/GamepadController.java | 6 +- .../controller/gamepad/GamepadState.java | 84 ++++++++++++++----- .../controlify/driver/GyroDriver.java | 8 +- .../controlify/driver/SDL2GamepadDriver.java | 2 +- .../controlify/driver/SteamDeckDriver.java | 4 +- .../screen/ControllerCalibrationScreen.java | 8 +- .../screen/ControllerConfigScreenFactory.java | 4 +- .../controlify/ingame/InGameInputHandler.java | 51 +++++------ .../assets/controlify/lang/en_us.json | 2 +- 10 files changed, 110 insertions(+), 61 deletions(-) diff --git a/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadConfig.java b/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadConfig.java index a4d949a..d06eca7 100644 --- a/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadConfig.java +++ b/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadConfig.java @@ -17,7 +17,7 @@ public class GamepadConfig extends ControllerConfig { public boolean flickStick = false; public boolean invertGyroX = false; public boolean invertGyroY = false; - public GamepadState.GyroState gyroCalibration = GamepadState.GyroState.ORIGIN; + public GamepadState.GyroState gyroCalibration = new GamepadState.GyroState(); public BuiltinGamepadTheme theme = BuiltinGamepadTheme.DEFAULT; diff --git a/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadController.java b/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadController.java index d0de281..ed4ccd6 100644 --- a/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadController.java +++ b/src/main/java/dev/isxander/controlify/controller/gamepad/GamepadController.java @@ -20,7 +20,7 @@ public class GamepadController extends AbstractController uniqueDrivers; @@ -86,8 +86,8 @@ public class GamepadController extends AbstractController deadzoneCalibration = new HashMap<>(); - private GamepadState.GyroState accumulatedGyroVelocity = GamepadState.GyroState.ORIGIN; + private GamepadState.GyroState accumulatedGyroVelocity = new GamepadState.GyroState(); public ControllerCalibrationScreen(Controller controller, Screen parent) { this(controller, () -> parent); @@ -121,7 +121,7 @@ public class ControllerCalibrationScreen extends Screen { if (stateChanged()) { calibrationTicks = 0; deadzoneCalibration.clear(); - accumulatedGyroVelocity = GamepadState.GyroState.ORIGIN; + accumulatedGyroVelocity = new GamepadState.GyroState(); } if (calibrationTicks < CALIBRATION_TIME) { @@ -154,7 +154,7 @@ public class ControllerCalibrationScreen extends Screen { private void processGyroData() { if (controller instanceof GamepadController gamepad && gamepad.hasGyro()) { - accumulatedGyroVelocity = accumulatedGyroVelocity.added(gamepad.drivers.gyroDriver().getGyroState()); + accumulatedGyroVelocity.add(gamepad.drivers.gyroDriver().getGyroState()); } } @@ -167,7 +167,7 @@ public class ControllerCalibrationScreen extends Screen { private void generateGyroCalibration() { if (controller instanceof GamepadController gamepad && gamepad.hasGyro()) { - gamepad.config().gyroCalibration = accumulatedGyroVelocity.divided(CALIBRATION_TIME); + gamepad.config().gyroCalibration = accumulatedGyroVelocity.div(CALIBRATION_TIME); } } diff --git a/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java b/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java index 6f98e83..6011d54 100644 --- a/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java +++ b/src/main/java/dev/isxander/controlify/gui/screen/ControllerConfigScreenFactory.java @@ -424,8 +424,8 @@ public class ControllerConfigScreenFactory { .build()) .binding(gpCfgDef.gyroLookSensitivity, () -> gpCfg.gyroLookSensitivity, v -> gpCfg.gyroLookSensitivity = v) .controller(opt -> FloatSliderControllerBuilder.create(opt) - .range(0f, 1f) - .step(0.05f) + .range(0f, 3f) + .step(0.1f) .valueFormatter(percentOrOffFormatter)) .listener((opt, sensitivity) -> gyroOptions.forEach(o -> { o.setAvailable(sensitivity > 0); diff --git a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java b/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java index b823a8b..f1c15c2 100644 --- a/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java +++ b/src/main/java/dev/isxander/controlify/ingame/InGameInputHandler.java @@ -17,8 +17,10 @@ import net.minecraft.client.player.KeyboardInput; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket; +import net.minecraft.util.Mth; import net.minecraft.world.InteractionHand; import net.minecraft.world.entity.player.Player; +import org.joml.Vector3f; import java.util.concurrent.atomic.AtomicReference; import java.util.function.BiFunction; @@ -27,12 +29,12 @@ public class InGameInputHandler { private final Controller controller; private final Minecraft minecraft; - private double lookInputX, lookInputY; - private boolean shouldShowPlayerList; - - private GamepadState.GyroState gyroInput = GamepadState.GyroState.ORIGIN; + private double lookInputX, lookInputY; // in degrees per tick + private final GamepadState.GyroState gyroInput = new GamepadState.GyroState(); private boolean wasAiming; + private boolean shouldShowPlayerList; + private final NavigationHelper dropRepeatHelper; public InGameInputHandler(Controller controller) { @@ -106,15 +108,6 @@ public class InGameInputHandler { minecraft.levelRenderer.needsUpdate(); } - - if (controller.bindings().INVENTORY.justPressed()) { - if (minecraft.gameMode.isServerControlledInventory()) { - minecraft.player.sendOpenInventory(); - } else { - minecraft.getTutorial().onOpenInventory(); - minecraft.setScreen(new InventoryScreen(minecraft.player)); - } - } } if (controller.bindings().TOGGLE_HUD_VISIBILITY.justPressed()) { minecraft.options.hideGui = !minecraft.options.hideGui; @@ -157,10 +150,12 @@ public class InGameInputHandler { // 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); - impulseY *= Math.abs(impulseY); + impulseX *= Math.abs(impulseX) * 10f; // 10 degrees per second + impulseY *= Math.abs(impulseY) * 10f; + impulseX *= controller.config().horizontalLookSensitivity; + impulseY *= controller.config().verticalLookSensitivity; - if (controller.config().reduceAimingSensitivity && player != null && player.isUsingItem()) { + if (controller.config().reduceAimingSensitivity && player.isUsingItem()) { float aimMultiplier = switch (player.getUseItem().getUseAnimation()) { case BOW, CROSSBOW, SPEAR -> 0.6f; case SPYGLASS -> 0.2f; @@ -177,23 +172,29 @@ public class InGameInputHandler { if (gamepad.config().gyroRequiresButton) { if (gamepad.bindings().GAMEPAD_GYRO_BUTTON.justPressed() || (isAiming && !wasAiming)) - gyroInput = GamepadState.GyroState.ORIGIN; + gyroInput.set(0); if (gamepad.bindings().GAMEPAD_GYRO_BUTTON.held() || isAiming) { if (gamepad.config().relativeGyroMode) - gyroInput = gyroInput.added(gamepad.state().gyroDelta().multiplied(0.1f)); + gyroInput.add(new Vector3f(gamepad.state().gyroDelta()).mul(0.1f)); else - gyroInput = gamepad.state().gyroDelta(); + gyroInput.set(gamepad.state().gyroDelta()); useGyro = true; } } else { - gyroInput = gamepad.state().gyroDelta(); + gyroInput.set(gamepad.state().gyroDelta()); useGyro = true; } if (useGyro) { - impulseY += -gyroInput.pitch() * gamepad.config().gyroLookSensitivity * (gamepad.config().invertGyroY ? -1 : 1); - impulseX += (-gyroInput.roll() + -gyroInput.yaw()) * gamepad.config().gyroLookSensitivity * (gamepad.config().invertGyroX ? -1 : 1); + // convert radians per second into degrees per tick + GamepadState.GyroState thisInput = new GamepadState.GyroState(gyroInput) + .mul(Mth.RAD_TO_DEG) + .div(20) + .mul(gamepad.config().gyroLookSensitivity); + + impulseY += -thisInput.pitch() * (gamepad.config().invertGyroY ? -1 : 1); + impulseX += (-thisInput.roll() + -thisInput.yaw()) * (gamepad.config().invertGyroX ? -1 : 1); } } @@ -201,15 +202,15 @@ public class InGameInputHandler { impulseX = lookInputModifier.modifyX(impulseX, controller); impulseY = lookInputModifier.modifyY(impulseY, controller); - lookInputX = impulseX * controller.config().horizontalLookSensitivity * 65f; - lookInputY = impulseY * controller.config().verticalLookSensitivity * 65f; + lookInputX = impulseX; + lookInputY = impulseY; wasAiming = isAiming; } public void processPlayerLook(float deltaTime) { if (minecraft.player != null) { - minecraft.player.turn(lookInputX * deltaTime, lookInputY * deltaTime); + minecraft.player.turn(lookInputX / 0.15f * deltaTime, lookInputY / 0.15f * deltaTime); } } diff --git a/src/main/resources/assets/controlify/lang/en_us.json b/src/main/resources/assets/controlify/lang/en_us.json index 10ec24a..2580b55 100644 --- a/src/main/resources/assets/controlify/lang/en_us.json +++ b/src/main/resources/assets/controlify/lang/en_us.json @@ -79,7 +79,7 @@ "controlify.gui.group.gyro.tooltip": "Adjust how Controlify treats your controller's built in gyroscope.\nA gyroscope determines how the controller is rotated.", "controlify.gui.group.gyro.no_gyro.tooltip": "This controller does not support Gyro. You must have a DualSenseā„¢ controller or other compatible controller to use this feature.", "controlify.gui.gyro_look_sensitivity": "Look Sensitivity", - "controlify.gui.gyro_look_sensitivity.tooltip": "How much the camera moves based on gyroscope rotation.\nThe pitch (rotating your controller forward/backward) is used for looking up and down, whilst both the roll (rotating your controller left/right) and yaw (rotating your controller clockwise/anticlockwise) are used for looking left and right.", + "controlify.gui.gyro_look_sensitivity.tooltip": "The percentage of the real-world rotation of your controller to use as look input. For example, rotating your controller 90 degrees, will move the camera 90 degrees, at 100%.\nThe pitch of your controller is used as up/down and the roll and yaw is used for left/right.\nThis sensitivity is completely independent of the regular horizontal and vertical sensitivity settings.", "controlify.gui.gyro_behaviour": "Gyro Behaviour", "controlify.gui.gyro_behaviour.tooltip": "How the gyroscope input should be interpreted as look input.", "controlify.gui.gyro_behaviour.absolute": "Absolute",