全景iOS

时间:2017-05-15 21:09:32

标签: ios swift quaternions panoramas

因此,我生成了一个漂亮的全景查看器,但相机指向下方。这意味着如果我把手机放在桌子上就像平板一样,它会旋转并很好地环顾球体。我希望能够保持正常(向上)并环顾四周。这是我的代码。

我有一个我在这里使用的扩展程序:

import UIKit
import SceneKit
import CoreMotion

extension CMDeviceMotion {

func gaze(atOrientation orientation: UIInterfaceOrientation) -> SCNVector4 {

    let attitude = self.attitude.quaternion
    let aq = GLKQuaternionMake(Float(attitude.x), Float(attitude.y), Float(attitude.z), Float(attitude.w))

    let final: SCNVector4

    switch UIApplication.shared.statusBarOrientation {

    case .landscapeRight:

        let cq = GLKQuaternionMakeWithAngleAndAxis(Float(Double.pi), 0, 1, 0)
        let q = GLKQuaternionMultiply(cq, aq)

        final = SCNVector4(x: -q.y, y: q.x, z: q.z, w: q.w)

    case .landscapeLeft:

        let cq = GLKQuaternionMakeWithAngleAndAxis(Float(-Double.pi), 0, 1, 0)
        let q = GLKQuaternionMultiply(cq, aq)

        final = SCNVector4(x: q.y, y: -q.x, z: q.z, w: q.w)

    case .portraitUpsideDown:

        let cq = GLKQuaternionMakeWithAngleAndAxis(Float(Double.pi), 1, 0, 0)
        let q = GLKQuaternionMultiply(cq, aq)

        final = SCNVector4(x: -q.x, y: -q.y, z: q.z, w: q.w)

    case .unknown:

        fallthrough

    case .portrait:

        let cq = GLKQuaternionMakeWithAngleAndAxis(Float(-Double.pi), 1, 0, 0)
        let q = GLKQuaternionMultiply(cq, aq)

        final = SCNVector4(x: q.x, y: q.y, z: q.z, w: q.w)
    }

    return final
}
}

然后viewcontroller看起来像这样:

import UIKit
import SceneKit
import CoreMotion

class ViewController: UIViewController {

let motionManager = CMMotionManager()
let cameraNode = SCNNode()


@IBOutlet weak var sceneView: SCNView!

override func viewDidLoad() {
    super.viewDidLoad()

    guard let imagePath = Bundle.main.path(forResource: "Hellbrunn25", ofType: "jpg") else {
        fatalError("Failed to find path for panaromic file.")
    }
    guard let image = UIImage(contentsOfFile:imagePath) else {
        fatalError("Failed to load panoramic image")
    }

    let scene = SCNScene()
    sceneView.scene = scene
    sceneView.allowsCameraControl = true

    //Create node, containing a sphere, using the panoramic image as a texture
    let sphere = SCNSphere(radius: 20.0)
    sphere.firstMaterial!.isDoubleSided = true
    sphere.firstMaterial!.diffuse.contents = image
    let sphereNode = SCNNode(geometry: sphere)
    sphereNode.position = SCNVector3Make(0,0,0)
    scene.rootNode.addChildNode(sphereNode)

    // Camera, ...
    cameraNode.camera = SCNCamera()
    cameraNode.position = SCNVector3Make(0, 0, 0)
    scene.rootNode.addChildNode(cameraNode)

    guard motionManager.isDeviceMotionAvailable else {
        fatalError("Device motion is not available")
    }

    // Action
    motionManager.deviceMotionUpdateInterval = 1.0 / 60.0
    motionManager.startDeviceMotionUpdates(to: OperationQueue.main, withHandler: {
       (deviceDidMove, Error)-> Void in

        let attitude: CMAttitude = deviceDidMove!.attitude

        self.cameraNode.orientation = SCNVector4Make(Float(attitude.quaternion.x), Float(attitude.quaternion.y), Float(attitude.quaternion.z), Float(attitude.quaternion.w))


    })

}
   override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func deviceDidMove(motion: CMDeviceMotion?, error: NSError?) {

    if let motion = motion {
        let orientation = motion.gaze(atOrientation: UIApplication.shared.statusBarOrientation)
        cameraNode.orientation = orientation
    }
}


}

如何让相机在图像上朝前。感谢

1 个答案:

答案 0 :(得分:0)

如果其他人正在寻找答案,我想出来了。我将肖像模式案例更改为以下内容:

let cq = GLKQuaternionMakeWithAngleAndAxis(Float(-Double.pi*0.5), 1, 0, 0)
let q = GLKQuaternionMultiply(cq, aq)

final = SCNVector4(x: q.x, y: q.y, z: q.z, w: q.w)