dotnet / maui

.NET MAUI is the .NET Multi-platform App UI, a framework for building native device applications spanning mobile, tablet, and desktop.
https://dot.net/maui
MIT License
22.01k stars 1.73k forks source link

OrientationSensor using Game Rotation Vector #15710

Open kezzyhko opened 1 year ago

kezzyhko commented 1 year ago

Description

On Android, there are multiple different orientation sensors: one uses magnetometer and one does not. The latter allows you to get phone's orientation relative to some fixed reference, not using Earth's magnetic field.

So I propose exposing this feature through MAUI API by GameOrientationSensor, which works using Game Rotation Vector.

Public API Changes

I imagine the API would look the same as normal OrientationSensor, so

private void ToggleOrientation()
{
    if (GameOrientationSensor.Default.IsSupported)
    {
        if (!GameOrientationSensor.Default.IsMonitoring)
        {
            // Turn on orientation
            GameOrientationSensor.Default.ReadingChanged += Orientation_ReadingChanged;
            GameOrientationSensor.Default.Start(SensorSpeed.UI);
        }
        else
        {
            // Turn off orientation
            GameOrientationSensor.Default.Stop();
            GameOrientationSensor.Default.ReadingChanged -= Orientation_ReadingChanged;
        }
    }
}

private void Orientation_ReadingChanged(object sender, GameOrientationSensorChangedEventArgs e)
{
    // Update UI Label with orientation state
    OrientationLabel.TextColor = Colors.Green;
    OrientationLabel.Text = $"Orientation: {e.Reading}";
}

Intended Use-Case

For some applications (usually games), the app does not need to know how the phone is oriented relative to north, it just needs some relative orientation. Sacrifising allignment to north, it is possible to get more stable and more percise orientation. It allows for more pleasant character controls, without random rotating/drifting due to uncalibrated compass.

kezzyhko commented 1 year ago

I have found the similar issue on different Accelerometer types in Android So, alternative API would be the following:

public static void Start(SensorSpeed sensorSpeed, OrientationSensorType? orientationSensorType);
public enum OrientationSensorType
{
    GeomagneticOrientation = 0,
    GameOrientation = 1,
}
OrientationSensor.Start(SensorSpeed.Game, OrientationSensorType.GameRotationVector);

And on other platforms where it is not supported, it would fall back to OrientationSensorType.Geomagnetic