基于Android设备方向的Xamarin.Android与UrhoSharp相机节点旋转

基于Android设备方向的Xamarin.Android与UrhoSharp相机节点旋转,android,xamarin,camera,rotation,urhosharp,Android,Xamarin,Camera,Rotation,Urhosharp,在我的Xamarin.Android应用程序中,我从设备的地磁旋转矢量复合传感器中获得X、Y、Z轴的方向数据,并使用该方法进行处理。我想在CameraNode的属性上应用场景中的此方向数据。 换句话说,我想使用设备“方向”传感器控制场景的摄影机 到目前为止,我在事件处理程序中所做的: // app -> an instance of Urho.SimpleApplication public void OnSensorChanged(SensorEvent e) { if (e.S

在我的Xamarin.Android应用程序中,我从设备的地磁旋转矢量复合传感器中获得X、Y、Z轴的方向数据,并使用该方法进行处理。我想在CameraNode的属性上应用场景中的此方向数据。 换句话说,我想使用设备“方向”传感器控制场景的摄影机

到目前为止,我在事件处理程序中所做的:

// app -> an instance of Urho.SimpleApplication
public void OnSensorChanged(SensorEvent e) {
    if (e.Sensor.Type == SensorType.GeomagneticRotationVector) {
        var rm = new float[9];
        SensorManager.GetRotationMatrixFromVector(rm, e.Values.ToArray());
        var ov = new float[3];
        SensorManager.GetOrientation(rm, ov);
        app.Pitch = (Urho.MathHelper.RadiansToDegrees(ov[0]) + 360) % 360;      // map [-Pi...+Pi] to [0...360]
        app.Yaw = (Urho.MathHelper.RadiansToDegrees(ov[1]) + 360) % 360;        // map [-Pi/2...+Pi/2] to [0...360]
        app.CameraNode.Rotation = new Urho.Quaternion(app.Pitch, app.Yaw, 0);
    }
}

但不幸的是,它并没有像预期的那样工作,而且相机总是朝着错误的方向。有什么想法吗?

传感器更改的
应该是:

   if (e.Sensor == mRotationSensor)
    {
        var rm = new float[9];
        SensorManager.GetRotationMatrixFromVector(rm, e.Values.ToArray());
        var ov = new float[3];
        SensorManager.GetOrientation(rm, ov);
        app.pitch = (Urho.MathHelper.RadiansToDegrees(ov[1]) + 360) % 360;      // map [-Pi...+Pi] to [0...360]
        app.yaw = (Urho.MathHelper.RadiansToDegrees(ov[0]) + 360) % 360;
        Log.Error("pitch=",app.pitch+"");
        Log.Error("yaw=", app.yaw + "");
        // map [-Pi/2...+Pi/2] to [0...360]
        app.cameraNode.Rotation = new Urho.Quaternion(app.pitch, app.yaw, 0);

    }
您需要在
OnCreate
方法中为您的
SensorManager
添加以下内容:

 mSensorManager = (SensorManager)GetSystemService(Activity.SensorService);
 mRotationSensor = mSensorManager.GetDefaultSensor(SensorType.RotationVector);
 mSensorManager.RegisterListener(this, mRotationSensor, SensorDelay.Game);
并添加变量:

 private SensorManager mSensorManager;
 private Sensor mRotationSensor;
最后,不要忘记为您的活动实现
isSensorEventListener
接口


我在

上提供了一个演示,最后我通过@joe的研究和帮助解决了这个问题

以下是方法的最终版本:

// [app] is an instance of Urho.SimpleApplication
public void OnSensorChanged(SensorEvent e) {
    if (e.Sensor.Type == SensorType.GeomagneticRotationVector) {
        var inR = new float[9];
        SensorManager.GetRotationMatrixFromVector(inR, e.Values.ToArray());
        var outR = new float[9];
        // we need to remap cooridante system, since the Y and Z axes will be swapped, when we pick up the device 
        if (SensorManager.RemapCoordinateSystem(inR, Android.Hardware.Axis.X, Android.Hardware.Axis.Z, outR)) {
            var ov = new float[3];
            SensorManager.GetOrientation(outR, ov);
            try {
                app.Pitch = (MathHelper.RadiansToDegrees(ov[1]) + 360) % 360;
                app.Yaw = (MathHelper.RadiansToDegrees(ov[0]) + 360) % 360;
                app.CameraNode.Rotation = new Quaternion(app.Pitch, app.Yaw, 0);
            }
            catch (System.Exception ex) {
                // while Urho.SimpleApplication is not fully started, the [app] properties are not available
                System.Diagnostics.Trace.WriteLine(ex.Message);
            }
        }
    }
}

使用四元数的另一种可能的解决方案:

public void OnSensorChanged(SensorEvent e) {
    if (e.Sensor.Type == SensorType.GeomagneticRotationVector) {
        var qv = new float[4];
        SensorManager.GetQuaternionFromVector(qv, e.Values.ToArray());
        try {
            app.CameraNode.Rotation = new Quaternion(qv[1], -qv[3], qv[2], qv[0]);
            app.CameraNode.Pitch(90.0f);
            app.CameraNode.Roll(180.0f);
        }
        catch (System.Exception ex) {
        }
    }
}

Hello@joe lv msft根据您的示例修改了我的OnSensorChanged,但仍然不是很好。我想要达到的是类似于应用程序中的功能。基本上我想写我自己的天文馆应用程序与实时天空视图。你运行我的演示?它能在你的手机上运行吗?我看看SkyView@joe-lv msft将尝试它。我会让你知道的。顺便说一句,Android SDK也提供了一个方法,也许它更适合这个场景。或者?为什么我在我的Google play商店里找不到这个应用呢?不知道,但是还有很多类似的应用,例如。我们可以在下午聊天吗?你可以通过或[聚会](拉迪斯拉夫)联系我。heller@gmail.com)顺便说一句,我试过你的应用程序,它不能处理设备上没有SensorType.RotationVector传感器的情况。