1
0
forked from Clones/Controlify

✏️ Greatly improve gyro control

This commit is contained in:
isXander
2023-06-04 12:08:03 +01:00
parent 5669ea9b3a
commit daee2de327
8 changed files with 73 additions and 13 deletions

View File

@ -11,6 +11,8 @@ public class GamepadConfig extends ControllerConfig {
public float gyroLookSensitivity = 0f;
public boolean gyroRequiresButton = true;
public boolean flickStick = false;
public boolean invertGyroX = false;
public boolean invertGyroY = false;
public BuiltinGamepadTheme theme = BuiltinGamepadTheme.DEFAULT;

View File

@ -85,7 +85,9 @@ public class GamepadController extends AbstractController<GamepadState, GamepadC
}
}
GamepadState.GyroState gyroState = drivers.gyroDriver().getGyroState();
// todo: make this configurable
GamepadState.GyroState gyroState = drivers.gyroDriver().getGyroState().deadzone(0.05f);
this.absoluteGyro = this.absoluteGyro.add(gyroState);
state = new GamepadState(deadzoneAxesState, basicState.axes(), basicState.buttons(), gyroState, absoluteGyro);
}

View File

@ -209,5 +209,13 @@ public final class GamepadState implements ControllerState {
public GyroState add(GyroState other) {
return new GyroState(pitch + other.pitch, yaw + other.yaw, roll + other.roll);
}
public GyroState deadzone(float deadzone) {
return new GyroState(
Math.max(pitch - deadzone, 0) + Math.min(pitch + deadzone, 0),
Math.max(yaw - deadzone, 0) + Math.min(yaw + deadzone, 0),
Math.max(roll - deadzone, 0) + Math.min(roll + deadzone, 0)
);
}
}
}

View File

@ -15,15 +15,23 @@ public class SDL2GamepadDriver implements GyroDriver, RumbleDriver, BatteryDrive
this.ptrGamepad = SDL.SDL_GameControllerOpen(jid);
this.isGyroSupported = SDL.SDL_GameControllerHasSensor(ptrGamepad, SDL.SDL_SENSOR_GYRO);
this.isRumbleSupported = SDL.SDL_GameControllerHasRumble(ptrGamepad);
if (this.isGyroSupported()) {
SDL.SDL_GameControllerSetSensorEnabled(ptrGamepad, SDL.SDL_SENSOR_GYRO, true);
}
}
@Override
public void update() {
if (isGyroSupported()) {
float[] gyro = new float[3];
SDL.SDL_GameControllerGetSensorData(ptrGamepad, SDL.SDL_SENSOR_GYRO, gyro, 3);
gyroDelta = new GamepadState.GyroState(gyro[0], gyro[1], gyro[2]);
if (DebugProperties.PRINT_GYRO) Controlify.LOGGER.info("Gyro delta: " + gyroDelta);
if (SDL.SDL_GameControllerGetSensorData(ptrGamepad, SDL.SDL_SENSOR_GYRO, gyro, 3) == 0) {
gyroDelta = new GamepadState.GyroState(gyro[0], gyro[1], gyro[2]);
if (DebugProperties.PRINT_GYRO) Controlify.LOGGER.info("Gyro delta: " + gyroDelta);
} else {
Controlify.LOGGER.error("Could not get gyro data: " + SDL.SDL_GetError());
}
}
SDL.SDL_GameControllerUpdate();
}

View File

@ -418,6 +418,26 @@ public class ControllerConfigScreenFactory {
o.requestSetDefault();
}))
.build());
gyroGroup.option(Util.make(() -> {
var opt = Option.<Boolean>createBuilder()
.name(Component.translatable("controlify.gui.gyro_invert_x"))
.description(OptionDescription.of(Component.translatable("controlify.gui.gyro_invert_x.tooltip")))
.binding(gpCfgDef.invertGyroX, () -> gpCfg.invertGyroX, v -> gpCfg.invertGyroX = v)
.controller(TickBoxControllerBuilder::create)
.build();
gyroOptions.add(opt);
return opt;
}));
gyroGroup.option(Util.make(() -> {
var opt = Option.<Boolean>createBuilder()
.name(Component.translatable("controlify.gui.gyro_invert_y"))
.description(OptionDescription.of(Component.translatable("controlify.gui.gyro_invert_y.tooltip")))
.binding(gpCfgDef.invertGyroY, () -> gpCfg.invertGyroY, v -> gpCfg.invertGyroY = v)
.controller(TickBoxControllerBuilder::create)
.build();
gyroOptions.add(opt);
return opt;
}));
gyroGroup.option(Util.make(() -> {
var opt = Option.<Boolean>createBuilder()
.name(Component.translatable("controlify.gui.gyro_requires_button"))

View File

@ -6,6 +6,8 @@ import dev.isxander.controlify.api.ingameinput.LookInputModifier;
import dev.isxander.controlify.controller.Controller;
import dev.isxander.controlify.api.event.ControlifyEvents;
import dev.isxander.controlify.controller.gamepad.GamepadController;
import dev.isxander.controlify.utils.Animator;
import dev.isxander.controlify.utils.Easings;
import dev.isxander.controlify.utils.NavigationHelper;
import net.minecraft.client.CameraType;
import net.minecraft.client.Minecraft;
@ -15,7 +17,10 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.network.protocol.game.ServerboundPlayerActionPacket;
import net.minecraft.world.InteractionHand;
import org.joml.Vector2f;
import org.joml.Vector2fc;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiFunction;
public class InGameInputHandler {
@ -130,13 +135,20 @@ public class InGameInputHandler {
if (gamepad != null && gamepad.config().flickStick) {
var turnAngle = 90 / 0.15f; // Entity#turn multiplies cursor delta by 0.15 to get rotation
player.turn(
(controller.bindings().LOOK_RIGHT.justPressed() ? turnAngle : 0)
- (controller.bindings().LOOK_LEFT.justPressed() ? turnAngle : 0),
(controller.bindings().LOOK_DOWN.justPressed() ? turnAngle : 0)
- (controller.bindings().LOOK_UP.justPressed() ? turnAngle : 0)
AtomicReference<Float> lastAngle = new AtomicReference<>(0f);
Vector2fc flickVec = new Vector2f(
controller.bindings().LOOK_RIGHT.justPressed() ? 1 : controller.bindings().LOOK_LEFT.justPressed() ? -1 : 0,
controller.bindings().LOOK_DOWN.justPressed() ? 1 : controller.bindings().LOOK_UP.justPressed() ? -1 : 0
);
if (!flickVec.equals(0, 0)) {
Animator.INSTANCE.play(new Animator.AnimationInstance(10, Easings::easeOutExpo)
.addConsumer(angle -> {
player.turn((angle - lastAngle.get()) * flickVec.x(), (angle - lastAngle.get()) * flickVec.y());
lastAngle.set(angle);
}, 0, turnAngle));
}
return;
}
@ -161,10 +173,10 @@ public class InGameInputHandler {
&& gamepad.hasGyro()
&& (!gamepad.config().gyroRequiresButton || gamepad.bindings().GAMEPAD_GYRO_BUTTON.held())
) {
var gyroDelta = gamepad.state().gyroDelta();
var gyroDelta = gamepad.absoluteGyroState().deadzone(0.05f);
impulseX += (gyroDelta.yaw() + gyroDelta.pitch()) * gamepad.config().gyroLookSensitivity;
impulseY += gyroDelta.roll() * gamepad.config().gyroLookSensitivity;
impulseY += -gyroDelta.pitch() * gamepad.config().gyroLookSensitivity * (gamepad.config().invertGyroY ? -1 : 1);
impulseX += (-gyroDelta.roll() + -gyroDelta.yaw()) * gamepad.config().gyroLookSensitivity * (gamepad.config().invertGyroX ? -1 : 1);
}
LookInputModifier lookInputModifier = ControlifyEvents.LOOK_INPUT_MODIFIER.invoker();

View File

@ -8,4 +8,8 @@ public class Easings {
public static float easeOutQuad(float t) {
return 1 - (1 - t) * (1 - t);
}
public static float easeOutExpo(float t) {
return t == 1 ? 1 : 1 - (float) Math.pow(2, -10 * t);
}
}