如何将 ARPlaneAnchor 放置在与 ARImageAnchor 相同的位置
How to put an ARPlaneAnchor at the same location as an ARImageAnchor
我正在尝试将 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)
}
但 "got here 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 }
只是因为不能同时有两个anchor...
存在 ARPlaneAnchor
或 ARImageAnchor
。
根据您上次的回复更新,这将使您获得这些属性:
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
大小:
我正在尝试将 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)
}
但 "got here 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 }
只是因为不能同时有两个anchor...
存在 ARPlaneAnchor
或 ARImageAnchor
。
根据您上次的回复更新,这将使您获得这些属性:
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
大小: