问题
How do I get notified when the app has detected at least one plane in ARKit?
I'm currently doing something like this but it's not firing/it's not related:
extension MyViewController: ARSCNViewDelegate, ARSessionDelegate {
internal func setupAR() {
let scene = SCNScene()
sceneView.scene = scene
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = [.horizontal]
sceneView.session.delegate = self
sceneView.session.run(configuration)
}
public func session(_ session: ARSession, didUpdate anchors: [ARAnchor]) {
if !anchors.isEmpty {
print("ANCHORS NOT EMPTY")
planesDetectedState()
} else {
print("Anchors is empty")
}
}
}
回答1:
Please add Anchors first to update those. You need to use the following function:
func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
guard let frame = session.currentFrame else { return }
print("Just added an anchor and felt so good")
}
Plus, you wouldn't be able to see any plane, unless you add a node to you anchor, which you can do by:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
// Add a planeNode and make it a child to the node automatically added.
}
I would furthermore suggest, download the starter code which would be easy to follow for exactly the thing you are thinking about.
https://developer.apple.com/documentation/arkit/building_your_first_ar_experience
回答2:
If you want to detect ARAnchors
there are several ways to do so.
1st: You can use the ARSessionDelegate
Callback:
public func session(_ session: ARSession, didAdd anchors: [ARAnchor]) { }
Which:
Tells the delegate that one or more anchors have been added to the session.
An example of using this callback would thus be like so:
extension UIViewController: ARSessionDelegate{
public func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
//1. If We Have At Least One ARAnchor Detected The Log The Information
if !anchors.isEmpty {
anchors.forEach { (anchor) in
print("""
The Type Of Anchor = \(anchor.classForCoder)
The Anchor Identifier = \(anchor.identifier)
The Anchor Translation = X: \(anchor.transform.columns.3.x), Y: \(anchor.transform.columns.3.y), Z: \(anchor.transform.columns.3.z)
""")
}
}
}
}
2nd: You could use the ARSCNViewDelegate
callback:
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor)
Which:
Tells the delegate that a SceneKit node corresponding to a new AR anchor has been added to the scene.
An example of using this callback would thus be like so:
extension ViewController: ARSCNViewDelegate{
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
//1. Check An ARPlane Anchor Has Been Detected
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
//2. Get The Width & Height Of The Plane
let width = CGFloat(planeAnchor.extent.x)
let height = CGFloat(planeAnchor.extent.z)
//3. Create An SCNPlane So We Can Visualize The Plane Detected
let plane = SCNPlane(width: width, height: height)
//4. Set It's Colour
plane.materials.first?.diffuse.contents = UIColor.cyan
//5. Create An SCNNode To Hold Our Plane
let planeNode = SCNNode(geometry: plane)
//6. Position & Rotate It
let x = CGFloat(planeAnchor.center.x)
let y = CGFloat(planeAnchor.center.y)
let z = CGFloat(planeAnchor.center.z)
planeNode.position = SCNVector3(x,y,z)
planeNode.eulerAngles.x = -.pi / 2
//7. Add It To The Node For Anchor
node.addChildNode(planeNode)
}
}
来源:https://stackoverflow.com/questions/50354915/detect-planes-in-arkit