説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

AndroidSensors.cs 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. #if UNITY_EDITOR || UNITY_ANDROID || PACKAGE_DOCS_GENERATION
  2. using System;
  3. using System.ComponentModel;
  4. using System.Runtime.InteropServices;
  5. using UnityEngine.InputSystem.Android.LowLevel;
  6. using UnityEngine.InputSystem.LowLevel;
  7. using UnityEngine.InputSystem.Utilities;
  8. using UnityEngine.InputSystem.Layouts;
  9. using UnityEngine.InputSystem.Processors;
  10. ////TODO: make all the sensor class types internal
  11. namespace UnityEngine.InputSystem.Android.LowLevel
  12. {
  13. internal enum AndroidSensorType
  14. {
  15. None = 0,
  16. Accelerometer = 1,
  17. MagneticField = 2,
  18. Orientation = 3, // Was deprecated in API 8 https://developer.android.com/reference/android/hardware/Sensor#TYPE_ORIENTATION
  19. Gyroscope = 4,
  20. Light = 5,
  21. Pressure = 6,
  22. Temperature = 7, // Was deprecated in API 14 https://developer.android.com/reference/android/hardware/Sensor#TYPE_TEMPERATURE
  23. Proximity = 8,
  24. Gravity = 9,
  25. LinearAcceleration = 10,
  26. RotationVector = 11,
  27. RelativeHumidity = 12,
  28. AmbientTemperature = 13,
  29. MagneticFieldUncalibrated = 14,
  30. GameRotationVector = 15,
  31. GyroscopeUncalibrated = 16,
  32. SignificantMotion = 17,
  33. StepDetector = 18,
  34. StepCounter = 19,
  35. GeomagneticRotationVector = 20,
  36. HeartRate = 21,
  37. Pose6DOF = 28,
  38. StationaryDetect = 29,
  39. MotionDetect = 30,
  40. HeartBeat = 31,
  41. LowLatencyOffBodyDetect = 34,
  42. AccelerometerUncalibrated = 35,
  43. }
  44. [Serializable]
  45. internal struct AndroidSensorCapabilities
  46. {
  47. public AndroidSensorType sensorType;
  48. public string ToJson()
  49. {
  50. return JsonUtility.ToJson(this);
  51. }
  52. public static AndroidSensorCapabilities FromJson(string json)
  53. {
  54. if (json == null)
  55. throw new ArgumentNullException(nameof(json));
  56. return JsonUtility.FromJson<AndroidSensorCapabilities>(json);
  57. }
  58. public override string ToString()
  59. {
  60. return $"type = {sensorType.ToString()}";
  61. }
  62. }
  63. [StructLayout(LayoutKind.Sequential)]
  64. internal unsafe struct AndroidSensorState : IInputStateTypeInfo
  65. {
  66. public static FourCC kFormat = new FourCC('A', 'S', 'S', ' ');
  67. ////FIXME: Sensors to check if values matches old system
  68. // Accelerometer - OK
  69. // MagneticField - no alternative in old system
  70. // Gyroscope - OK
  71. // Light - no alternative in old system
  72. // Pressure - no alternative in old system
  73. // Proximity - no alternative in old system
  74. // Gravity - OK
  75. // LinearAcceleration - need to check
  76. // RotationVector - OK
  77. // RelativeHumidity - no alternative in old system
  78. // AmbientTemperature - no alternative in old system
  79. // GameRotationVector - no alternative in old system
  80. // StepCounter - no alternative in old system
  81. // GeomagneticRotationVector - no alternative in old system
  82. // HeartRate - no alternative in old system
  83. [InputControl(name = "acceleration", layout = "Vector3", processors = "AndroidCompensateDirection", variants = "Accelerometer")]
  84. [InputControl(name = "magneticField", layout = "Vector3", variants = "MagneticField")]
  85. // Note: Using CompensateDirection instead of AndroidCompensateDirection, because we don't need to normalize velocity
  86. [InputControl(name = "angularVelocity", layout = "Vector3", processors = "CompensateDirection", variants = "Gyroscope")]
  87. [InputControl(name = "lightLevel", layout = "Axis", variants = "Light")]
  88. [InputControl(name = "atmosphericPressure", layout = "Axis", variants = "Pressure")]
  89. [InputControl(name = "distance", layout = "Axis", variants = "Proximity")]
  90. [InputControl(name = "gravity", layout = "Vector3", processors = "AndroidCompensateDirection", variants = "Gravity")]
  91. [InputControl(name = "acceleration", layout = "Vector3", processors = "AndroidCompensateDirection", variants = "LinearAcceleration")]
  92. [InputControl(name = "attitude", layout = "Quaternion", processors = "AndroidCompensateRotation", variants = "RotationVector")]
  93. [InputControl(name = "relativeHumidity", layout = "Axis", variants = "RelativeHumidity")]
  94. [InputControl(name = "ambientTemperature", layout = "Axis", variants = "AmbientTemperature")]
  95. [InputControl(name = "attitude", layout = "Quaternion", processors = "AndroidCompensateRotation", variants = "GameRotationVector")]
  96. [InputControl(name = "stepCounter", layout = "Integer", variants = "StepCounter")]
  97. [InputControl(name = "rotation", layout = "Quaternion", processors = "AndroidCompensateRotation", variants = "GeomagneticRotationVector")]
  98. [InputControl(name = "rate", layout = "Axis", variants = "HeartRate")]
  99. public fixed float data[16];
  100. public AndroidSensorState WithData(params float[] data)
  101. {
  102. if (data == null)
  103. throw new ArgumentNullException(nameof(data));
  104. for (var i = 0; i < data.Length && i < 16; i++)
  105. this.data[i] = data[i];
  106. // Fill the rest with zeroes
  107. for (var i = data.Length; i < 16; i++)
  108. this.data[i] = 0.0f;
  109. return this;
  110. }
  111. public FourCC format => kFormat;
  112. }
  113. [DesignTimeVisible(false)]
  114. internal class AndroidCompensateDirectionProcessor : CompensateDirectionProcessor
  115. {
  116. // Taken from platforms\android-<API>\arch-arm\usr\include\android\sensor.h
  117. private const float kSensorStandardGravity = 9.80665f;
  118. private const float kAccelerationMultiplier = -1.0f / kSensorStandardGravity;
  119. public override Vector3 Process(Vector3 vector, InputControl control)
  120. {
  121. return base.Process(vector * kAccelerationMultiplier, control);
  122. }
  123. }
  124. [DesignTimeVisible(false)]
  125. internal class AndroidCompensateRotationProcessor : CompensateRotationProcessor
  126. {
  127. public override Quaternion Process(Quaternion value, InputControl control)
  128. {
  129. // https://developer.android.com/reference/android/hardware/SensorEvent#values
  130. // "...The rotation vector represents the orientation of the device as a combination of an angle and an axis, in which the device has rotated through an angle theta around an axis <x, y, z>."
  131. // "...The three elements of the rotation vector are < x * sin(theta / 2), y* sin(theta / 2), z* sin(theta / 2)>, such that the magnitude of the rotation vector is equal to sin(theta / 2), and the direction of the rotation vector is equal to the direction of the axis of rotation."
  132. // "...The three elements of the rotation vector are equal to the last three components of a unit quaternion < cos(theta / 2), x* sin(theta/ 2), y* sin(theta / 2), z* sin(theta/ 2)>."
  133. //
  134. // In other words, axis + rotation is combined into Vector3, to recover the quaternion from it, we must compute 4th component as 1 - sqrt(x*x + y*y + z*z)
  135. var sinRho2 = value.x * value.x + value.y * value.y + value.z * value.z;
  136. value.w = (sinRho2 < 1.0f) ? Mathf.Sqrt(1.0f - sinRho2) : 0.0f;
  137. return base.Process(value, control);
  138. }
  139. }
  140. }
  141. namespace UnityEngine.InputSystem.Android
  142. {
  143. /// <summary>
  144. /// Accelerometer device on Android.
  145. /// </summary>
  146. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_ACCELEROMETER"/>
  147. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "Accelerometer", hideInUI = true)]
  148. public class AndroidAccelerometer : Accelerometer
  149. {
  150. }
  151. /// <summary>
  152. /// Magnetic field sensor device on Android.
  153. /// </summary>
  154. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_MAGNETIC_FIELD"/>
  155. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "MagneticField", hideInUI = true)]
  156. public class AndroidMagneticFieldSensor : MagneticFieldSensor
  157. {
  158. }
  159. /// <summary>
  160. /// Gyroscope device on android.
  161. /// </summary>
  162. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_GYROSCOPE"/>
  163. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "Gyroscope", hideInUI = true)]
  164. public class AndroidGyroscope : Gyroscope
  165. {
  166. }
  167. /// <summary>
  168. /// Light sensor device on Android.
  169. /// </summary>
  170. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_LIGHT"/>
  171. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "Light", hideInUI = true)]
  172. public class AndroidLightSensor : LightSensor
  173. {
  174. }
  175. /// <summary>
  176. /// Pressure sensor device on Android.
  177. /// </summary>
  178. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_PRESSURE"/>
  179. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "Pressure", hideInUI = true)]
  180. public class AndroidPressureSensor : PressureSensor
  181. {
  182. }
  183. /// <summary>
  184. /// Proximity sensor type on Android.
  185. /// </summary>
  186. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_PROXIMITY"/>
  187. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "Proximity", hideInUI = true)]
  188. public class AndroidProximity : ProximitySensor
  189. {
  190. }
  191. /// <summary>
  192. /// Gravity sensor device on Android.
  193. /// </summary>
  194. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_GRAVITY"/>
  195. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "Gravity", hideInUI = true)]
  196. public class AndroidGravitySensor : GravitySensor
  197. {
  198. }
  199. /// <summary>
  200. /// Linear acceleration sensor device on Android.
  201. /// </summary>
  202. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_LINEAR_ACCELERATION"/>
  203. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "LinearAcceleration", hideInUI = true)]
  204. public class AndroidLinearAccelerationSensor : LinearAccelerationSensor
  205. {
  206. }
  207. /// <summary>
  208. /// Rotation vector sensor device on Android.
  209. /// </summary>
  210. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_ROTATION_VECTOR"/>
  211. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "RotationVector", hideInUI = true)]
  212. public class AndroidRotationVector : AttitudeSensor
  213. {
  214. }
  215. /// <summary>
  216. /// Relative humidity sensor device on Android.
  217. /// </summary>
  218. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_RELATIVE_HUMIDITY"/>
  219. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "RelativeHumidity", hideInUI = true)]
  220. public class AndroidRelativeHumidity : HumiditySensor
  221. {
  222. }
  223. /// <summary>
  224. /// Ambient temperature sensor device on Android.
  225. /// </summary>
  226. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_AMBIENT_TEMPERATURE"/>
  227. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "AmbientTemperature", hideInUI = true)]
  228. public class AndroidAmbientTemperature : AmbientTemperatureSensor
  229. {
  230. }
  231. /// <summary>
  232. /// Game rotation vector sensor device on Android.
  233. /// </summary>
  234. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_GAME_ROTATION_VECTOR"/>
  235. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "GameRotationVector", hideInUI = true)]
  236. public class AndroidGameRotationVector : AttitudeSensor
  237. {
  238. }
  239. /// <summary>
  240. /// Step counter sensor device on Android.
  241. /// </summary>
  242. /// <seealso href="https://developer.android.com/reference/android/hardware/Sensor#TYPE_STEP_COUNTER"/>
  243. [InputControlLayout(stateType = typeof(AndroidSensorState), variants = "StepCounter", hideInUI = true)]
  244. public class AndroidStepCounter : StepCounter
  245. {
  246. }
  247. }
  248. #endif