gpt4 book ai didi

swift - 无法区分 ARKit 检测到的平面和使用 HitTest 放置的数字对象

转载 作者:可可西里 更新时间:2023-11-01 01:09:08 25 4
gpt4 key购买 nike

我对 iOS Swift 编程还很陌生。我正在使用 ARKit 构建一个非常基本的应用程序来检测水平面并在其上放置、平移、旋转、修改或删除对象。

我主要关心的是 ARKit 检测到的平面与我放置的数字对象之间的差异。我的想法是使用 hitTest(:options:) 选择对象(如果有的话)并使用 hitTest(:types:) 通过点击手势选择平面。我在下面附上了相关的代码片段。

@objc func tapped(_ gesture: UITapGestureRecognizer){

let sceneView = gesture.view as! ARSCNView

let location = gesture.location(in: sceneView)


let hitTestOptions: [SCNHitTestOption: Any] = [.boundingBoxOnly: true]
let existingNodeHitTest = sceneView.hitTest(location, options: hitTestOptions)

if let existingNode = existingNodeHitTest.first?.node {

// Move, rotate, modify or delete the object

} else {

// Option to add other objects

let hitTest = sceneView.hitTest(location, types: .existingPlaneUsingExtent)

if !hitTest.isEmpty {

let node = findNode(at: location)

if node !== selectedNode {

self.addItems(hitTestResult: hitTest.first!)


}

}

}

}

func addItems(hitTestResult: ARHitTestResult) {


let scene = SCNScene(named: "BuildingModels.scnassets/model/model.scn")


let itemNode = (scene?.rootNode.childNode(withName: "SketchUp", recursively: false))!


let transform = hitTestResult.worldTransform
let position = SCNVector3(transform.columns.3.x,transform.columns.3.y,transform.columns.3.z)
itemNode.position = position
// self.sceneView.scene.lightingEnvironment.contents = scene.lightingEnvironment.contents

self.sceneView.scene.rootNode.addChildNode(itemNode)
selectedNode = itemNode

}

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

let gridNode = createGrid(planeAnchor: planeAnchor)
node.addChildNode(gridNode)


}

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

node.enumerateChildNodes { (childNode, _) in
childNode.removeFromParentNode()
}

let gridNode = createGrid(planeAnchor: planeAnchor)
node.addChildNode(gridNode)

}

当我运行代码时,hitTest(_:options:) 返回检测到的平面。有什么方法可以只选择我放置的 SCNNodes(对象)而不是检测到的平面。我错过了什么吗?非常感谢任何帮助。

谢谢,

苏拉布。

最佳答案

看看你的问题,你已经完成了一半。

完整处理此问题的方法是在 UITapGestureRecognizer 函数中使用以下 HitTest 函数:

(1) ARSCNHitTest,它:

Searches for real-world objects or AR anchors in the captured camera image corresponding to a point in the SceneKit view.

(2) 一个SCNHitTest,它:

Looks for SCNGeometry objects along the ray you specify. For each intersection between the ray and and a geometry, SceneKit creates a hit-test result to provide information about both the SCNNode object containing the geometry and the location of the intersection on the geometry’s surface.

因此,以您的 UITapGestureRecognizer 为例,您可以像这样区分场景中的 ARPlaneAnchor (detectedPlane) 和任何 SCNNode:

@objc func handleTap(_ gesture: UITapGestureRecognizer){

//1. Get The Current Touch Location
let currentTouchLocation = gesture.location(in: self.augmentedRealityView)

//2. Perform An ARNSCNHitTest To See If We Have Hit An ARPlaneAnchor
if let planeHitTest = augmentedRealityView.hitTest(currentTouchLocation, types: .existingPlane).first,
let planeAnchor = planeHitTest.anchor as? ARPlaneAnchor{

print("User Has Tapped On An Existing Plane = \(planeAnchor.identifier)")
return
}

//3. Perform An SCNHitTest To See If We Have Hit An SCNNode
if let nodeHitTest = augmentedRealityView.hitTest(currentTouchLocation, options: nil).first {

let nodeTapped = nodeHitTest.node

print("An SCNNode Has Been Tapped = \(nodeTapped)")
return
}

}

如果您为您的任何 SCNNode 使用 name 属性,这也将进一步帮助您,例如:

if let name = nodeTapped.name{
print("An SCNNode Named \(name) Has Been Tapped")
}

此外,如果您只想检测已添加的对象,例如 SCNNodes,那么您只需删除 getureRecognizer 函数的第二部分即可。

希望对你有帮助

关于swift - 无法区分 ARKit 检测到的平面和使用 HitTest 放置的数字对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49506946/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com