MotionInput.cs 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using System;
  2. using System.Numerics;
  3. namespace Ryujinx.Modules.Motion
  4. {
  5. public class MotionInput
  6. {
  7. public ulong TimeStamp { get; set; }
  8. public Vector3 Accelerometer { get; set; }
  9. public Vector3 Gyroscrope { get; set; }
  10. public Vector3 Rotation { get; set; }
  11. private readonly MotionSensorFilter _filter;
  12. private int _calibrationFrame = 0;
  13. public MotionInput()
  14. {
  15. TimeStamp = 0;
  16. Accelerometer = new Vector3();
  17. Gyroscrope = new Vector3();
  18. Rotation = new Vector3();
  19. // TODO: RE the correct filter.
  20. _filter = new MotionSensorFilter(0f);
  21. }
  22. public void Update(Vector3 accel, Vector3 gyro, ulong timestamp, int sensitivity, float deadzone)
  23. {
  24. if (TimeStamp != 0)
  25. {
  26. if (gyro.Length() <= 1f && accel.Length() >= 0.8f && accel.Z >= 0.8f)
  27. {
  28. _calibrationFrame++;
  29. if (_calibrationFrame >= 90)
  30. {
  31. gyro = Vector3.Zero;
  32. Rotation = Vector3.Zero;
  33. _filter.Reset();
  34. _calibrationFrame = 0;
  35. }
  36. }
  37. else
  38. {
  39. _calibrationFrame = 0;
  40. }
  41. Accelerometer = -accel;
  42. if (gyro.Length() < deadzone)
  43. {
  44. gyro = Vector3.Zero;
  45. }
  46. gyro *= (sensitivity / 100f);
  47. Gyroscrope = gyro;
  48. float deltaTime = MathF.Abs((long)(timestamp - TimeStamp) / 1000000f);
  49. Vector3 deltaGyro = gyro * deltaTime;
  50. Rotation += deltaGyro;
  51. _filter.SamplePeriod = deltaTime;
  52. _filter.Update(accel, DegreeToRad(gyro));
  53. }
  54. TimeStamp = timestamp;
  55. }
  56. public Matrix4x4 GetOrientation()
  57. {
  58. return Matrix4x4.CreateFromQuaternion(_filter.Quaternion);
  59. }
  60. private static Vector3 DegreeToRad(Vector3 degree)
  61. {
  62. return degree * (MathF.PI / 180);
  63. }
  64. }
  65. }