我正在尝试将ARImageAnchor与ARPlaneAnchor放置在相同的位置,但是它不起作用。我认为这是问题所在的renderer函数的开始:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
        guard let imageAnchor = anchor as? ARImageAnchor else { return }
        guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
        ...
}


当我注释掉与planeAnchor有关的所有内容时,它都可以正常工作,但是一旦我尝试将它们放在相同的位置,它仍然可以编译,但不会检测到参考图像。有人以前遇到过这样的问题吗?谢谢!

更新:将sceneView作为我的ARSCNView,我使用以下代码:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    print("got here")
    guard let touchLocation = touches.first?.location(in: sceneView),
        let hitTest = sceneView?.hitTest(touchLocation, options: nil),
        //let detectedPlane = planes[planeAnchor],
        let nodeTapped = hitTest.first?.node,
        let nodeName = nodeTapped.name else { return }
    print("got here 2")

    print(nodeName)

}


但是“我在这里2”从未打印过,当我在飞机上点击时什么也没有发生。我应该怎么做?

最佳答案

再看一遍,我不可能。

如果您将ARWorldTrackingConfiguration设置为检测飞机,例如:

  configuration.planeDetection = .horizontal


然后在委托方法中添加以下调试日志:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

    print(anchor.classForCoder)

}


您将看到,当检测到目标图像时,它将记录ARImageAnchor,而如果检测到水平面,它将记录:ARPlaneAnchor

这就是您的警卫声明不执行的原因:

 guard let planeAnchor = anchor as? ARPlaneAnchor else { return }


只是因为不能同时有两个锚点...

ARPlaneAnchorARImageAnchor

根据您的上一个响应进行的更新,它将使您能够获得以下属性:

   func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

    //1. If Out Target Image Has Been Detected Than Get The Corresponding Anchor
    guard let currentImageAnchor = anchor as? ARImageAnchor else { return }

    //2. Get The Targets Name
    let name = currentImageAnchor.referenceImage.name!

    //3. Get The Targets Width & Height
    let width = currentImageAnchor.referenceImage.physicalSize.width
    let height = currentImageAnchor.referenceImage.physicalSize.height

    //4. Log The Reference Images Information
    print("""
    Image Name = \(name)
    Image Width = \(width)
    Image Height = \(height)
    """)
}


我仍然不明白,但是为什么您还需要一个PlaneAnchor,您可以使用它来显示模型等:)

如果要在该锚点添加一些东西,请尝试以下操作:

  /// Generates An SCNPlane On The Detected Image At The Size Of The Target
///
/// - Parameters:
///   - node: SCNNode
///   - width: CGFloat
///   - height: CGFloat
func generateModel(_ node: SCNNode, width: CGFloat, height: CGFloat){

    let nodeToAdd = SCNNode()
    let planeGeometry = SCNPlane(width: width, height: height)
    planeGeometry.firstMaterial?.diffuse.contents = UIColor.red
    nodeToAdd.geometry = planeGeometry
    nodeToAdd.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)
    node.addChildNode(nodeToAdd)
}


并在委托方法中调用它:

 generateModel(node, width: width, height: height)


我认为这是您要实现的目标。

更新:要在添加的节点上获得hitTest,只需使用touchesBegan例如

   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    guard let touch = touches.first?.location(in: self.augmentedRealityView),
    let hitTest = self.augmentedRealityView?.hitTest(touch, options: nil),
    let nodeTapped = hitTest.first?.node,
    let nodeName = nodeTapped.name else { return }

    print(nodeName)

}


更新:
如果放置在ImageAnchor上的对象似乎不稳定,则可能是您在ARAssets Bundle中错误地设置了referenceImage大小:

ios - 如何将ARPlaneAnchor与ARImageAnchor放在同一位置-LMLPHP

07-24 21:36