菜鸟教程小白 发表于 2022-12-13 15:58:04

ios - VR 中的 SceneKit 摄像机移动


                                            <p><p>借助 <a href="https://github.com/stevenjs/VR-iOS-Experiment" rel="noreferrer noopener nofollow">https://github.com/stevenjs/VR-iOS-Experiment</a>,我为我的应用程序创建了 VR 版本</p>

<p>现在我想在我开始与手机一起移动时移动我的 cameraNode。我正在尝试从核心运动中使用 userAcceleration,但我不知道如何做到这一点。我也是核心运动的新手。</p>

<p>请帮我解决这个问题。</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>此代码将适应您的设备方向......它基本上是一个 sphereNode,中间有一个 cameraNode。 Core Motion 控制摄像机 View 。 </p>

<pre><code>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(&#34;Device motion is not available&#34;)
      }

      startCameraTracking()
      player?.isMuted = true
      player?.play()
    }


    func createSphereNode(material: AnyObject?) -&gt; 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) {
            (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) -&gt; 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(&#34;Default&#34;)
      }

      return final
    }
}
</code></pre></p>
                                   
                                                <p style="font-size: 20px;">关于ios - VR 中的 SceneKit 摄像机移动,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/36679913/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/36679913/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - VR 中的 SceneKit 摄像机移动