diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h index 09c401b3295..3441dac6f31 100644 --- a/platform/iphone/app_delegate.h +++ b/platform/iphone/app_delegate.h @@ -30,11 +30,16 @@ #import "gl_view.h" #import "view_controller.h" -@interface AppDelegate : NSObject { +// Old accelerometer approach deprecated since IOS 7.0 +// Include coremotion for accelerometer, gyroscope and magnetometer access, available since IOS 4.0 but some functionality won't work for anything before IOS 5.0 +#import + +//@interface AppDelegate : NSObject { +@interface AppDelegate : NSObject { //@property (strong, nonatomic) UIWindow *window; ViewController* view_controller; - UIAccelerationValue accel[3]; - UIAccelerationValue last_accel[3]; +// UIAccelerationValue accel[3]; +// UIAccelerationValue last_accel[3]; }; @property (strong, nonatomic) UIWindow *window; diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index feb87e742fd..f65599a35af 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -84,6 +84,9 @@ extern char** gargv; extern int iphone_main(int, int, int, char**); extern void iphone_finish(); +CMMotionManager *motionManager; +bool motionInitialised; + static ViewController* mainViewController = nil; + (ViewController*) getViewController { @@ -195,7 +198,22 @@ static int frame_count = 0; default: { if (OSIPhone::get_singleton()) { - OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1], accel[2]); +// OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1], accel[2]); + if (motionInitialised) { + // Just using polling approach for now, we can set this up so it sends data to us in intervals, might be better. + // See Apple reference pages for more details: + // https://developer.apple.com/reference/coremotion/cmmotionmanager?language=objc + CMAcceleration acceleration = motionManager.deviceMotion.userAcceleration; + OSIPhone::get_singleton()->update_accelerometer(acceleration.x, acceleration.y, acceleration.z); + + CMMagneticField magnetic = motionManager.deviceMotion.magneticField.field; + OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z); + + ///@TODO we can access rotationRate as a CMRotationRate variable (processed date) or CMGyroData (raw data), have to see what works best + CMRotationRate rotation = motionManager.deviceMotion.rotationRate; + OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z); + } + bool quit_request = OSIPhone::get_singleton()->iterate(); }; @@ -253,11 +271,24 @@ static int frame_count = 0; [window makeKeyAndVisible]; //Configure and start accelerometer +/* + Old accelerometer approach deprecated since IOS 7.0 + last_accel[0] = 0; last_accel[1] = 0; last_accel[2] = 0; [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)]; [[UIAccelerometer sharedAccelerometer] setDelegate:self]; +*/ + + if (!motionInitialised) { + motionManager = [[CMMotionManager alloc] init]; + if (motionManager.deviceMotionAvailable) { + motionManager.deviceMotionUpdateInterval = 1.0/70.0; + [motionManager startDeviceMotionUpdates]; + motionInitialised = YES; + }; + }; //OSIPhone::screen_width = rect.size.width - rect.origin.x; //OSIPhone::screen_height = rect.size.height - rect.origin.y; @@ -297,12 +328,23 @@ static int frame_count = 0; - (void)applicationWillTerminate:(UIApplication*)application { printf("********************* will terminate\n"); + + if (motionInitialised) { + ///@TODO is this the right place to clean this up? + [motionManager stopDeviceMotionUpdates]; + // no free ? + motionManager = nil; + motionInitialised = NO; + }; + iphone_finish(); }; - (void)applicationDidEnterBackground:(UIApplication *)application { printf("********************* did enter background\n"); + ///@TODO maybe add pause motionManager? and where would we unpause it? + if (OS::get_singleton()->get_main_loop()) OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); [view_controller.view stopAnimation]; @@ -340,12 +382,15 @@ static int frame_count = 0; }; } +/* + Depricated since IOS 7.0 - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration { //Use a basic low-pass filter to only keep the gravity in the accelerometer values accel[0] = acceleration.x; // * kFilteringFactor + accel[0] * (1.0 - kFilteringFactor); accel[1] = acceleration.y; // * kFilteringFactor + accel[1] * (1.0 - kFilteringFactor); accel[2] = acceleration.z; // * kFilteringFactor + accel[2] * (1.0 - kFilteringFactor); } +*/ - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { #ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index b92b64e9f11..88ec83ef7ab 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -83,6 +83,7 @@ def configure(env): '-framework', 'CoreAudio', '-framework', 'CoreGraphics', '-framework', 'CoreMedia', + '-framework', 'CoreMotion', '-framework', 'Foundation', '-framework', 'Security', '-framework', 'UIKit', @@ -109,6 +110,7 @@ def configure(env): '-framework', 'MediaPlayer', '-framework', 'AVFoundation', '-framework', 'CoreMedia', + '-framework', 'CoreMotion', ]) else: env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=5.1.1', @@ -126,6 +128,7 @@ def configure(env): '-framework', 'MediaPlayer', '-framework', 'AVFoundation', '-framework', 'CoreMedia', + '-framework', 'CoreMotion', ]) if env['game_center'] == 'yes': diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index 1d12501aea1..a30d1c7194c 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -364,7 +364,13 @@ void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) { */ }; +void OSIPhone::update_magnetometer(float p_x, float p_y, float p_z) { + input->set_magnetometer(Vector3(p_x, p_y, p_z)); +}; +void OSIPhone::update_gyroscope(float p_x, float p_y, float p_z) { + input->set_gyroscope(Vector3(p_x, p_y, p_z)); +}; void OSIPhone::delete_main_loop() { diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 331b20afbfc..57e530f6493 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -153,6 +153,8 @@ public: int set_base_framebuffer(int p_fb); void update_accelerometer(float p_x, float p_y, float p_z); + void update_magnetometer(float p_x, float p_y, float p_z); + void update_gyroscope(float p_x, float p_y, float p_z); static OSIPhone* get_singleton();