Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using ARSCNPlaneGeometry #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 37 additions & 53 deletions FloorIsLava/ViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,24 @@ class ViewController: UIViewController, ARSCNViewDelegate {
// Create a SceneKit plane to visualize the node using its position and extent.

// Create the geometry and its materials
let plane = SCNPlane(width: CGFloat(anchor.extent.x), height: CGFloat(anchor.extent.z))
let plane: SCNGeometry
// Create a node with the plane geometry we created
let planeNode = SCNNode()

// SCNPlanes are vertically oriented in their local coordinate space.
// Rotate it to match the horizontal orientation of the ARPlaneAnchor.

if #available(iOS 11.3, *) {
plane = ARSCNPlaneGeometry(device: MTLCreateSystemDefaultDevice()!) ?? ARSCNPlaneGeometry()
(plane as! ARSCNPlaneGeometry).update(from: anchor.geometry)
} else {
// Fallback on earlier versions
plane = SCNPlane(width: CGFloat(anchor.extent.x), height: CGFloat(anchor.extent.z))
planeNode.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z)
planeNode.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)
}

planeNode.geometry = plane

let lavaImage = UIImage(named: "Lava")
let lavaMaterial = SCNMaterial()
Expand All @@ -68,17 +85,28 @@ class ViewController: UIViewController, ARSCNViewDelegate {

plane.materials = [lavaMaterial]

// Create a node with the plane geometry we created
let planeNode = SCNNode(geometry: plane)
planeNode.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z)

// SCNPlanes are vertically oriented in their local coordinate space.
// Rotate it to match the horizontal orientation of the ARPlaneAnchor.
planeNode.transform = SCNMatrix4MakeRotation(-Float.pi / 2, 1, 0, 0)

return planeNode
}

/// Update the geometry of the node when anchor updates
///
/// - Parameters:
/// - node: root node for the anchor
/// - anchor: ARPlaneAnchor of the detected surface
func updateGeometry(of node: SCNNode, with anchor: ARPlaneAnchor) {
guard let firstChild = node.childNodes.first else {
return
}
if #available(iOS 11.3, *), let plane = firstChild.geometry as? ARSCNPlaneGeometry {
plane.update(from: anchor.geometry)
} else if let plane = node.geometry as? SCNPlane {
plane.width = CGFloat(anchor.extent.x)
plane.height = CGFloat(anchor.extent.z)
node.position = SCNVector3Make(anchor.center.x, 0, anchor.center.z)
}
}

// Try with a floor node instead - this didn't work so well but leaving in for reference
func createFloorNode(anchor: ARPlaneAnchor) -> SCNNode {
let floor = SCNFloor()
Expand All @@ -99,14 +127,6 @@ class ViewController: UIViewController, ARSCNViewDelegate {

// MARK: - ARSCNViewDelegate

/*
// Override to create and configure nodes for anchors added to the view's session.
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let node = SCNNode()

return node
}
*/

// The following functions are automatically called when the ARSessionView adds, updates, and removes anchors

Expand All @@ -124,43 +144,7 @@ class ViewController: UIViewController, ARSCNViewDelegate {
// When a detected plane is updated, make a new planeNode
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let planeAnchor = anchor as? ARPlaneAnchor else { return }

// Remove existing plane nodes
node.enumerateChildNodes {
(childNode, _) in
childNode.removeFromParentNode()
}


let planeNode = createPlaneNode(anchor: planeAnchor)

node.addChildNode(planeNode)
}

// When a detected plane is removed, remove the planeNode
func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {
guard anchor is ARPlaneAnchor else { return }

// Remove existing plane nodes
node.enumerateChildNodes {
(childNode, _) in
childNode.removeFromParentNode()
}
self.updateGeometry(of: node, with: planeAnchor)
}


func session(_ session: ARSession, didFailWithError error: Error) {
// Present an error message to the user

}

func sessionWasInterrupted(_ session: ARSession) {
// Inform the user that the session has been interrupted, for example, by presenting an overlay

}

func sessionInterruptionEnded(_ session: ARSession) {
// Reset tracking and/or remove existing anchors if consistent tracking is required

}
}