mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-16 16:16:04 -04:00
Feat[Gyro]: Use sensor fusion implementation (#3998)
* Feat[Gyro]: Use sensor fusion implementation * Fix: Remove time factor It is pointless when mesuring an absolute rotation, since regardless how big the difference in timing is, we can get the same difference * Handle ORIENTATION_UNKNOWN * Cleanup unused timestamp saving code * Fix[Gyro]: inverted factors on edges I watch out for the screen surface rotation now * Fix[Gyro]: update rotation factors only on non unknown cases * Fix[gyro]: portrait factors on landscape upon start --------- Co-authored-by: artdeell <ultramaksim@gmail.com>
This commit is contained in:
parent
a84cd3a5f9
commit
292b56f26f
@ -1,31 +1,40 @@
|
|||||||
package net.kdt.pojavlaunch;
|
package net.kdt.pojavlaunch;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.hardware.Sensor;
|
import android.hardware.Sensor;
|
||||||
import android.hardware.SensorEvent;
|
import android.hardware.SensorEvent;
|
||||||
import android.hardware.SensorEventListener;
|
import android.hardware.SensorEventListener;
|
||||||
import android.hardware.SensorManager;
|
import android.hardware.SensorManager;
|
||||||
import android.view.OrientationEventListener;
|
import android.view.OrientationEventListener;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||||
|
|
||||||
import org.lwjgl.glfw.CallbackBridge;
|
import org.lwjgl.glfw.CallbackBridge;
|
||||||
|
|
||||||
public class GyroControl implements SensorEventListener, GrabListener{
|
public class GyroControl implements SensorEventListener, GrabListener{
|
||||||
|
private final WindowManager mWindowManager;
|
||||||
|
private int mSurfaceRotation;
|
||||||
private final SensorManager mSensorManager;
|
private final SensorManager mSensorManager;
|
||||||
private final Sensor mSensor;
|
private final Sensor mSensor;
|
||||||
private final OrientationCorrectionListener mCorrectionListener;
|
private final OrientationCorrectionListener mCorrectionListener;
|
||||||
private boolean mShouldHandleEvents;
|
private boolean mShouldHandleEvents;
|
||||||
private boolean mFirstPass;
|
private boolean mFirstPass;
|
||||||
private long mPreviousTimestamp;
|
|
||||||
private float xFactor; // -1 or 1 depending on device orientation
|
private float xFactor; // -1 or 1 depending on device orientation
|
||||||
private float yFactor;
|
private float yFactor;
|
||||||
private boolean mSwapXY;
|
private boolean mSwapXY;
|
||||||
|
|
||||||
public GyroControl(Context context) {
|
private final float[] mPreviousRotation = new float[16];
|
||||||
mSensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
private final float[] mCurrentRotation = new float[16];
|
||||||
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
|
private final float[] mAngleDifference = new float[3];
|
||||||
mCorrectionListener = new OrientationCorrectionListener(context);
|
|
||||||
|
public GyroControl(Activity activity) {
|
||||||
|
mWindowManager = activity.getWindowManager();
|
||||||
|
mSurfaceRotation = -10;
|
||||||
|
mSensorManager = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
|
||||||
|
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
|
||||||
|
mCorrectionListener = new OrientationCorrectionListener(activity);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enable() {
|
public void enable() {
|
||||||
@ -45,21 +54,20 @@ public class GyroControl implements SensorEventListener, GrabListener{
|
|||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public void onSensorChanged(SensorEvent sensorEvent) {
|
public void onSensorChanged(SensorEvent sensorEvent) {
|
||||||
if(mShouldHandleEvents && sensorEvent.sensor == mSensor) {
|
if (!mShouldHandleEvents) return;
|
||||||
float factor = LauncherPreferences.PREF_GYRO_SENSITIVITY;
|
// Copy the old array content
|
||||||
if(!mFirstPass) {
|
System.arraycopy(mCurrentRotation, 0, mPreviousRotation, 0, 16);
|
||||||
factor *= (sensorEvent.timestamp - mPreviousTimestamp) * 0.000001;
|
SensorManager.getRotationMatrixFromVector(mCurrentRotation, sensorEvent.values);
|
||||||
}else mFirstPass = false;
|
|
||||||
if(mSwapXY) {
|
if(mFirstPass){ // Setup initial position
|
||||||
float interm = sensorEvent.values[0];
|
mFirstPass = false;
|
||||||
sensorEvent.values[0] = sensorEvent.values[1];
|
return;
|
||||||
sensorEvent.values[1] = interm;
|
|
||||||
}
|
|
||||||
CallbackBridge.mouseX += sensorEvent.values[0] * factor * xFactor;
|
|
||||||
CallbackBridge.mouseY += sensorEvent.values[1] * factor * yFactor;
|
|
||||||
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
|
||||||
mPreviousTimestamp = sensorEvent.timestamp;
|
|
||||||
}
|
}
|
||||||
|
SensorManager.getAngleChange(mAngleDifference, mCurrentRotation, mPreviousRotation);
|
||||||
|
|
||||||
|
CallbackBridge.mouseX -= (mAngleDifference[mSwapXY ? 2 : 1] * 1000 * LauncherPreferences.PREF_GYRO_SENSITIVITY * xFactor);
|
||||||
|
CallbackBridge.mouseY += (mAngleDifference[mSwapXY ? 1 : 2] * 1000 * LauncherPreferences.PREF_GYRO_SENSITIVITY * yFactor);
|
||||||
|
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -81,10 +89,21 @@ public class GyroControl implements SensorEventListener, GrabListener{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onOrientationChanged(int i) {
|
public void onOrientationChanged(int i) {
|
||||||
|
// Force to wait to be in game before setting factors
|
||||||
|
// Theoretically, one could use the whole interface in portrait...
|
||||||
|
if(!mShouldHandleEvents) return;
|
||||||
|
int surfaceRotation = mWindowManager.getDefaultDisplay().getRotation();
|
||||||
|
if(surfaceRotation == mSurfaceRotation) return;
|
||||||
|
|
||||||
|
if(i == OrientationEventListener.ORIENTATION_UNKNOWN) {
|
||||||
|
return; //change nothing
|
||||||
|
}
|
||||||
|
mSurfaceRotation = surfaceRotation;
|
||||||
|
|
||||||
if((315 < i && i <= 360) || (i < 45) ) {
|
if((315 < i && i <= 360) || (i < 45) ) {
|
||||||
mSwapXY = true;
|
mSwapXY = true;
|
||||||
xFactor = 1;
|
xFactor = 1;
|
||||||
yFactor = -1;
|
yFactor = 1;
|
||||||
}else if(45 < i && i < 135) {
|
}else if(45 < i && i < 135) {
|
||||||
mSwapXY = false;
|
mSwapXY = false;
|
||||||
xFactor = 1;
|
xFactor = 1;
|
||||||
@ -92,7 +111,7 @@ public class GyroControl implements SensorEventListener, GrabListener{
|
|||||||
}else if(135 < i && i < 225) {
|
}else if(135 < i && i < 225) {
|
||||||
mSwapXY = true;
|
mSwapXY = true;
|
||||||
xFactor = -1;
|
xFactor = -1;
|
||||||
yFactor = 1;
|
yFactor = -1;
|
||||||
}else if(225 < i && i < 315) {
|
}else if(225 < i && i < 315) {
|
||||||
mSwapXY = false;
|
mSwapXY = false;
|
||||||
xFactor = -1;
|
xFactor = -1;
|
||||||
|
@ -54,7 +54,7 @@ public class LauncherPreferences {
|
|||||||
public static boolean PREF_JAVA_SANDBOX = true;
|
public static boolean PREF_JAVA_SANDBOX = true;
|
||||||
public static int PREF_SCALE_FACTOR = 100;
|
public static int PREF_SCALE_FACTOR = 100;
|
||||||
public static boolean PREF_ENALBE_GYRO = false;
|
public static boolean PREF_ENALBE_GYRO = false;
|
||||||
public static float PREF_GYRO_SENSITIVITY = 100;
|
public static float PREF_GYRO_SENSITIVITY = 1f;
|
||||||
public static int PREF_GYRO_SAMPLE_RATE = 16;
|
public static int PREF_GYRO_SAMPLE_RATE = 16;
|
||||||
|
|
||||||
public static boolean PREF_GYRO_INVERT_X = false;
|
public static boolean PREF_GYRO_INVERT_X = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user