[英]SceneKit camera movement in VR
I have created VR version to my application with the help of this https://github.com/stevenjs/VR-iOS-Experiment我在这个https://github.com/stevenjs/VR-iOS-Experiment的帮助下为我的应用程序创建了 VR 版本
Now I want move my cameraNode when I start moving along with my phone.现在,当我开始带着手机移动时,我想移动我的 cameraNode。 I'm trying to use userAcceleration from core motion, But I have no clue to how to do this.我正在尝试从核心运动中使用 userAcceleration,但我不知道如何执行此操作。 Also I'm new to core motion.我也是核心运动的新手。
Please help me to solve this.请帮我解决这个问题。
This code will adapt to your device orientation ... it is basically a sphereNode with a cameraNode in the middle.此代码将适应您的设备方向……它基本上是一个中间有一个 cameraNode 的 sphereNode。 Core Motion controls the camera view. Core Motion 控制相机视图。
import UIKit
import SceneKit
import CoreMotion
import SpriteKit
import AVFoundation
class Video360VC: UIViewController {
@IBOutlet weak var sceneView: SCNView!
let motionManager = CMMotionManager()
let cameraNode = SCNNode()
var player: AVPlayer?
override func viewDidLoad() {
super.viewDidLoad()
startSelected()
}
func startNewPlayer(fileURL: URL, fileURLSub: URL){
player = AVPlayer(url: fileURL)
let videoNode = SKVideoNode(avPlayer: player!)
let size = CGSize(width: 4096, height: 2048)
videoNode.size = size
videoNode.position = CGPoint(x: size.width/2, y: size.height/2)
let spriteScene = SKScene(size: size)
spriteScene.scaleMode = .resizeFill
spriteScene.addChild(videoNode)
let sphereNode = createSphereNode(material:spriteScene)
configureScene(node: sphereNode)
guard motionManager.isDeviceMotionAvailable else {
fatalError("Device motion is not available")
}
startCameraTracking()
player?.isMuted = true
player?.play()
}
func createSphereNode(material: AnyObject?) -> SCNNode {
let sphere = SCNSphere(radius: 20.0)
sphere.firstMaterial!.isDoubleSided = true
sphere.firstMaterial!.diffuse.contents = material
let sphereNode = SCNNode(geometry: sphere)
sphereNode.position = SCNVector3Make(0,0,0)
sphereNode.rotation = SCNVector4Make(1, 0, 0, Float.pi)
return sphereNode
}
func configureScene(node sphereNode: SCNNode) {
// Set the scene
let scene = SCNScene()
sceneView.scene = scene
//test mode help
sceneView.showsStatistics = false
sceneView.allowsCameraControl = false
// Camera, ...
cameraNode.camera = SCNCamera()
cameraNode.position = SCNVector3Make(0, 0, 0)
scene.rootNode.addChildNode(sphereNode)
scene.rootNode.addChildNode(cameraNode)
}
func startCameraTracking() {
motionManager.deviceMotionUpdateInterval = 1.0 / 60.0
motionManager.startDeviceMotionUpdates(to: OperationQueue.main) {
[weak self](data: CMDeviceMotion?, error: Error?) in
guard let data = data else { return }
self?.cameraNode.camera?.fieldOfView = 90
self?.cameraNode.orientation = data.gaze(atOrientation: .landscapeRight)
}
}
}
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 orientation {
case .landscapeRight:
let cq = GLKQuaternionMakeWithAngleAndAxis(Float(Float.pi/2), 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(-Float.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(Float.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(-Float.pi), 1, 0, 0)
let q = GLKQuaternionMultiply(cq, aq)
final = SCNVector4(x: q.x, y: q.y, z: q.z, w: q.w)
default:
print("Default")
}
return final
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.