azul_core/sensors.rs
1//! POD types for the motion-sensor surface
2//! (SUPER_PLAN_2 §1 feature 5 + research/03 §"Feature 5").
3//!
4//! The three raw sensors apps want — accelerometer, gyroscope,
5//! magnetometer — each delivered as an `(x, y, z)` triple in the sensor's
6//! natural unit. Defined here in `azul-core` so the manager + accessors
7//! cross the FFI without `azul-layout` being a dependency. The stateful
8//! side lives in `azul_layout::managers::sensors::SensorManager`.
9//!
10//! Coordinate frame (research/03 §coordinate-frame): right-handed,
11//! +X right, +Y up, +Z out of the screen toward the user, in the device's
12//! default-portrait frame (iOS keeps the device frame regardless of UI
13//! orientation; Android auto-rotates only fused sensors). v1 reports the
14//! raw device frame.
15
16/// Which motion sensor a [`SensorReading`] came from.
17#[repr(C)]
18#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
19pub enum SensorKind {
20 /// Linear acceleration including gravity, in **m/s²**
21 /// (iOS `CMAccelerometerData` ×9.80665, Android `TYPE_ACCELEROMETER`).
22 Accelerometer,
23 /// Angular velocity, in **rad/s** (iOS `CMGyroData`, Android
24 /// `TYPE_GYROSCOPE`).
25 Gyroscope,
26 /// Geomagnetic field, in **µT** (iOS `magneticField`, Android
27 /// `TYPE_MAGNETIC_FIELD`).
28 Magnetometer,
29}
30
31/// One `(x, y, z)` sample from a motion sensor. Units depend on
32/// [`SensorReading::kind`] (see [`SensorKind`]). All POD / `Copy`.
33#[repr(C)]
34#[derive(Debug, Clone, Copy, PartialEq)]
35pub struct SensorReading {
36 /// Which sensor produced this reading.
37 pub kind: SensorKind,
38 /// X axis (device frame: right), in the kind's unit.
39 pub x: f32,
40 /// Y axis (device frame: up), in the kind's unit.
41 pub y: f32,
42 /// Z axis (device frame: out of screen toward user), in the kind's unit.
43 pub z: f32,
44 /// Monotonic timestamp in milliseconds since program start.
45 pub timestamp_ms: u64,
46}
47
48impl SensorReading {
49 /// The magnitude of the `(x, y, z)` vector — e.g. total acceleration
50 /// (≈9.81 at rest for the accelerometer) or field strength.
51 pub fn magnitude(&self) -> f32 {
52 (self.x * self.x + self.y * self.y + self.z * self.z).sqrt()
53 }
54}
55
56// FFI Option wrapper for `CallbackInfo::get_sensor_reading(kind) ->
57// Option<SensorReading>` (mirrors `OptionLocationFix`).
58impl_option!(
59 SensorReading,
60 OptionSensorReading,
61 [Debug, Clone, Copy, PartialEq]
62);