cameranode rotate as iOS device moving

后端 未结 2 917
庸人自扰
庸人自扰 2020-12-05 11:53

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

相关标签:
2条回答
  • 2020-12-05 12:04

    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.

    0 讨论(0)
  • 2020-12-05 12:19

    Swift 5.0 / iOS 13 Update

    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
        })
    }
    
    0 讨论(0)
提交回复
热议问题