在 SceneKit 中使用 Vuforia 提供的投影矩阵和标记姿势

Using Vuforia provided Projection Matrix and Marker Pose in SceneKit

目前我正在尝试解决在 SceneKit 中渲染时投影矩阵和帧标记姿势的使用问题。场景中的模型和相机图像背景显示没有问题。但是,一旦我更改投影矩阵和帧标记姿势矩阵以匹配 Vuforia,所有内容都会被推到屏幕外。

func didUpdateProjectionMatrix(projectionMatrix: matrix_float4x4)
{
    let extrinsic = SCNMatrix4FromMat4(projectionMatrix)
    let camera = self.cameraNode?.camera
    camera?.setProjectionTransform(extrinsic)
}

func didUpdateFramemarkers(framemarkers: [Framemarker]?)
{
    guard let framemarkers = framemarkers else {
        return
    }

    for framemarker in framemarkers {
        let pose = SCNMatrix4Invert(SCNMatrix4FromMat4(framemarker.pose))
        self.objectNode?.transform = pose
    }
}

这是设置 SCNCamera 和对象节点的正确方法吗?设置 Vuforia 帧标记以与 SceneKit 一起工作是否还需要其他任何东西?

它很管用!

困难的部分是确定完成这项工作需要哪些 SceneKit。最初我阅读了文章 Making Augmented Reality app easily with Scenekit + Vuforia,其中概述了如何为用户定义的目标重新调整示例应用程序。该文章的缺点包括作者更改的内容并不总是很清楚,没有提供示例项目,并且它基于旧版本的 Vuforia。最终,我发现没有必要反转姿势矩阵。

绘制相机图像并设置投影矩阵并更新标记位姿

override func viewDidLoad() 
{
    super.viewDidLoad()

    let scene = SmartScanScene()

    let camera = SCNCamera()
    let cameraNode = SCNNode()
    cameraNode.camera = camera
    scene.rootNode.addChildNode(cameraNode)
    _cameraNode = cameraNode

    let view = self.view as! SCNView
    view.backgroundColor = UIColor.blackColor()
    view.showsStatistics = true
    // view.debugOptions = SCNDebugOptions.ShowBoundingBoxes.union(.ShowWireframe)
    view.autoenablesDefaultLighting = true
    view.allowsCameraControl = false
}

func didUpdateProjectionMatrix(projectionMatrix: matrix_float4x4)
{
    let extrinsic = SCNMatrix4FromMat4(projectionMatrix)
    _cameraNode?.camera?.setProjectionTransform(extrinsic)
}

func didUpdateFramemarkers(framemarkers: [Framemarker]?)
{
    guard let framemarkers = framemarkers else {
        return
    }

    for framemarker in framemarkers {
        let pose = SCNMatrix4FromMat4(framemarker.pose)
        self.objectNode?.transform = pose
    }
}

func didUpdateCameraImage(image: UIImage?)
{
    if let image = image {
        _scene?.background.contents = image
    }
}