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