全景 iOS
Panoramic View iOS
所以我生成了一个不错的全景查看器,但相机指向下方。这意味着如果我像 table 一样将我的 phone 平放,它会旋转并很好地环顾球体。我希望能够保持正常(向上)并环顾四周。这是我的代码。
我这里有一个扩展:
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
}
}
}
如何让相机在图像上面向前方。谢谢
如果其他人正在寻找答案,我想通了。我将纵向模式案例更改为以下内容:
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)
所以我生成了一个不错的全景查看器,但相机指向下方。这意味着如果我像 table 一样将我的 phone 平放,它会旋转并很好地环顾球体。我希望能够保持正常(向上)并环顾四周。这是我的代码。
我这里有一个扩展:
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
}
}
}
如何让相机在图像上面向前方。谢谢
如果其他人正在寻找答案,我想通了。我将纵向模式案例更改为以下内容:
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)