SLProject  4.3.020
A platform independent 3D computer graphics framework for desktop OS, Android, iOS and online in web browsers
SENSiOSOrientationDelegate.mm
Go to the documentation of this file.
2 #import <CoreMotion/CoreMotion.h>
3 #import <GLKit/GLKit.h>
4 
5 #include <SENSUtils.h>
6 
7 @interface SENSiOSOrientationDelegate () {
8 
9 @private
10  CMMotionManager* _motionManager;
11  BOOL _running;
12 }
13 
14 @end
15 
16 @implementation SENSiOSOrientationDelegate
17 
18 - (id)init
19 {
20  //Initialize the parent class(es) up the hierarchy and create self:
21  self = [super init];
22  //Initialize members (not necessary with ARC)
23  _motionManager = nil;
24  _running = NO;
25  if (self)
26  {
27  _motionManager = [[CMMotionManager alloc] init];
28  }
29 
30  return self;
31 }
32 
33 - (BOOL)start
34 {
35  if (_motionManager == nil)
36  return NO;
37 
38  if (!_running)
39  {
40  [self startMotionManager:1.0 / 20.0];
41  //[_motionManager startDeviceMotionUpdates];
42  _running = true;
43  printf("Starting Motion Manager\n");
44  }
45 
46  return YES;
47 }
48 
49 - (void)stop
50 {
51  if (_running)
52  {
53  [_motionManager stopDeviceMotionUpdates];
54  _running = false;
55  printf("Stopping Location Manager\n");
56  }
57 }
58 
59 //-----------------------------------------------------------------------------
60 //! Starts the motion data update if the interval time > 0 else it stops
61 - (void)startMotionManager:(double)intervalTimeSEC
62 {
63  if ([_motionManager isDeviceMotionAvailable] == YES)
64  {
65  _motionManager.deviceMotionUpdateInterval = intervalTimeSEC;
66 
67  // See also: https://developer.apple.com/documentation/coremotion/getting_processed_device_motion_data/understanding_reference_frames_and_device_attitude?language=objc
68 
69  // In case the compass calibration is turned off on the iOS device,
70  // the following code receives an error with code 102 - true north not available.
71  // This is why we use the magnetic north here.
72  [_motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical
73  toQueue:[NSOperationQueue currentQueue]
74  withHandler:^(CMDeviceMotion* motion, NSError* error) {
75  [self performSelectorOnMainThread:@selector(onDeviceMotionUpdate:)
76  withObject:motion
77  waitUntilDone:YES];
78  }];
79  }
80  else
81  {
82  [_motionManager stopDeviceMotionUpdates];
83  }
84 }
85 //-----------------------------------------------------------------------------
86 - (void)onDeviceMotionUpdate:(CMDeviceMotion*)motion
87 {
88  CMDeviceMotion* motionData = _motionManager.deviceMotion;
89  CMAttitude* attitude = motionData.attitude;
90 
91  //Get sensor rotation as quaternion. This quaternion describes a rotation relative to NWU-frame
92  //(see: https://developer.apple.com/documentation/coremotion/getting_processed_device_motion_data/understanding_reference_frames_and_device_attitude)
93  CMQuaternion q = attitude.quaternion;
94 
95  /*
96  //test w.r.t. to NWU-frame
97  if(_updateCB)
98  _updateCB(q.x, q.y, q.z, q.w);
99 
100  printf("Rotation: xRot %f yRot %f zRot %f\n", attitude.pitch * SENS_RAD2DEG, attitude.roll * SENS_RAD2DEG, attitude.yaw * SENS_RAD2DEG);
101  */
102 
103  //(https://developer.apple.com/documentation/coremotion/getting_processed_device-motion_data/understanding_reference_frames_and_device_attitude)
104  //We configure CMMotionManager with xMagneticNorthZVertical which means its a frame, where x points north, y points west and z points up (NWU).
105  //We add rotation of 90 deg. around z-axis to relate the sensor rotation to an ENU-frame (as in Android)
106  GLKQuaternion qNWU = GLKQuaternionMake(q.x, q.y, q.z, q.w);
107  GLKQuaternion qRot90Z = GLKQuaternionMakeWithAngleAndAxis(GLKMathDegreesToRadians(90), 0, 0, 1);
108  GLKQuaternion qENU = GLKQuaternionMultiply(qRot90Z, qNWU);
109 
110  // Send quaternion
111  if (_updateCB)
112  _updateCB(qENU.q[0], qENU.q[1], qENU.q[2], qENU.q[3]);
113 }
114 
115 @end
typedef void(SL_STDCALL *cbOnImGuiBuild)(SLScene *s
Callback function typedef for ImGui build function.