• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - VR 中的 SceneKit 摄像机移动

[复制链接]
菜鸟教程小白 发表于 2022-12-13 15:58:04 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

借助 https://github.com/stevenjs/VR-iOS-Experiment,我为我的应用程序创建了 VR 版本

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

请帮我解决这个问题。



Best Answer-推荐答案


此代码将适应您的设备方向......它基本上是一个 sphereNode,中间有一个 cameraNode。 Core Motion 控制摄像机 View 。

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
    }
}

关于ios - VR 中的 SceneKit 摄像机移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36679913/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap