It\'s 360 degree video player project.
I add a cameranode(SCNNode
) to a rootnode, the cameranode was put at the center(0,0,0) of the SCNSphere
Device motion is best, as it ties in multiple sensors and fuses the data together in a meaningful way. It's also best to avoid using euler angles, as they suffer from what's known as gimbal lock. Instead, use quaternions and set your camera orientation with them.
I've created a Swift class extension for CMDeviceMotion that'll let you determine what the device is looking at (for any orientation of the screen).
From there, it's straightforward to rotate your camera. First, setup your device motion (in view did appear, or some other appropriate place):
if motionManager.deviceMotionAvailable {
motionManager.deviceMotionUpdateInterval = 0.017
motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue(), withHandler: deviceDidMove)
}
Then handle those updates in your deviceDidMove implementation, using the previously mentioned CMDeviceMotion extension:
func deviceDidMove(motion: CMDeviceMotion?, error: NSError?) {
if let motion = motion {
yourCameraNode.orientation = motion.gaze(atOrientation: UIApplication.sharedApplication().statusBarOrientation)
}
}
And now your camera should follow your devices orientation in space.
using the brilliant extension from the initial answer, you can simply do something like this:
override func viewDidAppear(_ animated: Bool) {
// let motionManager = CMMotionManager() // definition made globally
// CoreMotion
motionManager.startDeviceMotionUpdates()
motionManager.deviceMotionUpdateInterval = 1.0 / 60.0
let interfaceOrientation = UIApplication.shared.windows.first(where: { $0.isKeyWindow })?.windowScene?.interfaceOrientation // for iOS13 and later
// .xTrueNorthZVertical // always aligns to the real north
// .xArbitraryZVertical // will use this one for initial direction
motionManager.startDeviceMotionUpdates(using: .xArbitraryZVertical, to: OperationQueue.main, withHandler: { (motion: CMDeviceMotion?, err: Error?) in
guard let m = motion else { return }
// self.cameraNode.orientation = m.gaze(atOrientation: UIApplication.shared.statusBarOrientation) // before iOS 13
self.cameraNode.orientation = m.gaze(atOrientation: interfaceOrientation!) // for iOS13 and later
})
}