@@ -15,10 +15,6 @@ class LocationSensorsHandler(
1515 gameViewModel : GameViewModel
1616) {
1717
18- private val accelerometerLastValues = AtomicReference <FloatArray ?>(null )
19- private val magneticFieldLastValues = AtomicReference <FloatArray ?>(null )
20- private val counter = AtomicInteger (0 )
21-
2218 private val sensorManager = context.getSystemService(SensorManager ::class .java)
2319 ? : throw Exception (" Sensor manager not found" )
2420
@@ -28,79 +24,101 @@ class LocationSensorsHandler(
2824 private val accelerometerSensor = sensorManager.getDefaultSensor(Sensor .TYPE_ACCELEROMETER )
2925 ? : throw Exception (" Accelerometer sensor not found" )
3026
31- private val magneticFieldListener: SensorEventListener = object : SensorEventListener {
27+ private val linearAccelerationSensor = sensorManager.getDefaultSensor(Sensor .TYPE_LINEAR_ACCELERATION )
28+ ? : throw Exception (" Linear acceleration sensor not found" )
29+
30+ // ============================================================================================ |
31+ // ================================= Device Orientation ======================================= |
32+ // ============================================================================================ |
33+
34+ private val orientationListener: SensorEventListener = object : SensorEventListener {
35+
36+ private val accelerometerLastValues = AtomicReference <FloatArray ?>(null )
37+ private val magneticFieldLastValues = AtomicReference <FloatArray ?>(null )
38+ private val counter = AtomicInteger (0 )
39+
3240 override fun onSensorChanged (event : SensorEvent ) {
3341 val (x,y,z) = event.values
34- magneticFieldLastValues.set(floatArrayOf(x,y,z))
42+ when (event.sensor.type) {
43+ Sensor .TYPE_MAGNETIC_FIELD -> magneticFieldLastValues.set(floatArrayOf(x,y,z))
44+ Sensor .TYPE_ACCELEROMETER -> accelerometerLastValues.set(floatArrayOf(x,y,z))
45+ }
3546 if (shouldEmitOrientationEvent()) {
3647 emitOrientationEvent(gameViewModel)
3748 }
3849 }
3950 override fun onAccuracyChanged (sensor : Sensor ? , accuracy : Int ) {}
51+
52+ private fun shouldEmitOrientationEvent (): Boolean {
53+ var new: Int
54+ do {
55+ val current = counter.get()
56+ new = (current + 1 ) % 2
57+ } while (! counter.compareAndSet(current,new))
58+ return new == 0
59+ }
60+
61+ @Suppress(" LocalVariableName" )
62+ private fun emitOrientationEvent (gameViewModel : GameViewModel ) {
63+ val magneticFieldValues = magneticFieldLastValues.get() ? : return
64+ val accelerometerValues = accelerometerLastValues.get() ? : return
65+
66+ val R = FloatArray (9 )
67+ val I = FloatArray (9 )
68+ val orientation = FloatArray (3 )
69+
70+ SensorManager .getRotationMatrix(R , I , accelerometerValues, magneticFieldValues)
71+ SensorManager .getOrientation(R , orientation)
72+
73+ val (azimuth,pitch,roll) = orientation
74+ val actor = gameViewModel.playerId
75+ val timestamp = gameViewModel.getCurrentGameTime()
76+ gameViewModel.addEvent(SessionEvent .orientationAzimuth(actor, timestamp, azimuth.toString()))
77+ gameViewModel.addEvent(SessionEvent .orientationPitch(actor, timestamp, pitch.toString()))
78+ gameViewModel.addEvent(SessionEvent .orientationRoll(actor, timestamp, roll.toString()))
79+ }
4080 }
4181
42- private val accelerometerListener: SensorEventListener = object : SensorEventListener {
82+ // ============================================================================================ |
83+ // ================================= Linear Acceleration ====================================== |
84+ // ============================================================================================ |
85+
86+ private val linearAccelerationListener: SensorEventListener = object : SensorEventListener {
4387 override fun onSensorChanged (event : SensorEvent ) {
4488 val (x,y,z) = event.values
45- accelerometerLastValues.set(floatArrayOf(x,y,z))
46-
4789 val actor = gameViewModel.playerId
4890 val timestamp = gameViewModel.getCurrentGameTime()
49- gameViewModel.addEvent(SessionEvent .accelerometerX(actor, timestamp, x.toString()))
50- gameViewModel.addEvent(SessionEvent .accelerometerY(actor, timestamp, y.toString()))
51- gameViewModel.addEvent(SessionEvent .accelerometerZ(actor, timestamp, z.toString()))
52-
53- if (shouldEmitOrientationEvent()) {
54- emitOrientationEvent(gameViewModel)
55- }
91+ gameViewModel.addEvent(SessionEvent .linearAccelerationX(actor, timestamp, x.toString()))
92+ gameViewModel.addEvent(SessionEvent .linearAccelerationY(actor, timestamp, y.toString()))
93+ gameViewModel.addEvent(SessionEvent .linearAccelerationZ(actor, timestamp, z.toString()))
5694 }
5795 override fun onAccuracyChanged (sensor : Sensor ? , accuracy : Int ) {}
5896 }
5997
98+ // ============================================================================================ |
99+ // =================================== Public API ============================================= |
100+ // ============================================================================================ |
101+
60102 fun start () {
61103 sensorManager.registerListener(
62- magneticFieldListener ,
104+ orientationListener ,
63105 magneticFieldSensor,
64106 SensorManager .SENSOR_DELAY_NORMAL
65107 )
66108 sensorManager.registerListener(
67- accelerometerListener ,
109+ orientationListener ,
68110 accelerometerSensor,
69111 SensorManager .SENSOR_DELAY_NORMAL
70112 )
113+ sensorManager.registerListener(
114+ linearAccelerationListener,
115+ linearAccelerationSensor,
116+ SensorManager .SENSOR_DELAY_NORMAL
117+ )
71118 }
72119
73120 fun stop () {
74- sensorManager.unregisterListener(magneticFieldListener)
75- sensorManager.unregisterListener(accelerometerListener)
76- }
77-
78- private fun shouldEmitOrientationEvent (): Boolean {
79- var new: Int
80- do {
81- val current = counter.get()
82- new = (current + 1 ) % 2
83- } while (! counter.compareAndSet(current,new))
84- return new == 0
85- }
86-
87- @Suppress(" LocalVariableName" )
88- private fun emitOrientationEvent (gameViewModel : GameViewModel ) {
89- val magneticFieldValues = magneticFieldLastValues.get() ? : return
90- val accelerometerValues = accelerometerLastValues.get() ? : return
91-
92- val R = FloatArray (9 )
93- val I = FloatArray (9 )
94- val orientation = FloatArray (3 )
95-
96- SensorManager .getRotationMatrix(R , I , accelerometerValues, magneticFieldValues)
97- SensorManager .getOrientation(R , orientation)
98-
99- val (azimuth,pitch,roll) = orientation
100- val actor = gameViewModel.playerId
101- val timestamp = gameViewModel.getCurrentGameTime()
102- gameViewModel.addEvent(SessionEvent .orientationAzimuth(actor, timestamp, azimuth.toString()))
103- gameViewModel.addEvent(SessionEvent .orientationPitch(actor, timestamp, pitch.toString()))
104- gameViewModel.addEvent(SessionEvent .orientationRoll(actor, timestamp, roll.toString()))
121+ sensorManager.unregisterListener(orientationListener)
122+ sensorManager.unregisterListener(linearAccelerationListener)
105123 }
106124}
0 commit comments