Skip to content

Instantly share code, notes, and snippets.

@GUIEEN
Forked from eospi/SceneKitLiDARMesh.swift
Created June 24, 2024 06:45
Show Gist options
  • Save GUIEEN/1ea363f07520d4767bed31cdc0c47fc4 to your computer and use it in GitHub Desktop.
Save GUIEEN/1ea363f07520d4767bed31cdc0c47fc4 to your computer and use it in GitHub Desktop.
import UIKit
import SceneKit
import ARKit
class ViewController: UIViewController, ARSCNViewDelegate {
@IBOutlet var sceneView: ARSCNView!
var anchorCount = 0
override func viewDidLoad() {
super.viewDidLoad()
// Set the view's delegate
sceneView.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Create a session configuration
let configuration = ARWorldTrackingConfiguration()
configuration.sceneReconstruction = .meshWithClassification
configuration.environmentTexturing = .automatic
sceneView.automaticallyUpdatesLighting = true
sceneView.autoenablesDefaultLighting = true
// Run the view's session
sceneView.session.run(configuration)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Pause the view's session
sceneView.session.pause()
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let meshAnchor = anchor as? ARMeshAnchor else { return }
let meshGeometry = ARSCNMeshGeometry(meshAnchor: meshAnchor)
meshGeometry.node.name = anchor.name
node.addChildNode(meshGeometry.node(material: UIColor.blue))
anchorCount += 1
}
// scene update independent of drawing
// data stays coherent for duration of render
// Xcode instruments for resource monitoring
/*
Game performance template
*/
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let meshAnchor = anchor as? ARMeshAnchor else { return }
if let previousMeshNode = sceneView.scene.rootNode.childNode(withName: meshAnchor.name ?? "", recursively: true) {
previousMeshNode.removeFromParentNode()
}
let meshGeometry = ARSCNMeshGeometry(meshAnchor: meshAnchor)
node.addChildNode(meshGeometry.node(material: UIColor.blue))
}
}
class ARSCNMeshGeometry {
let scnGeometry: SCNGeometry
var node: SCNNode {
return SCNNode(geometry: scnGeometry)
}
init(meshAnchor: ARMeshAnchor) {
let meshGeometry = meshAnchor.geometry
// Vertices source
let vertices = meshGeometry.vertices
let verticesSource = SCNGeometrySource(buffer: vertices.buffer, vertexFormat: vertices.format, semantic: .vertex, vertexCount: vertices.count, dataOffset: vertices.offset, dataStride: vertices.stride)
// Indices Element
let faces = meshGeometry.faces
let facesData = Data(bytesNoCopy: faces.buffer.contents(), count: faces.buffer.length, deallocator: .none)
let facesElement = SCNGeometryElement(data: facesData, primitiveType: .triangles, primitiveCount: faces.count, bytesPerIndex: faces.bytesPerIndex)
// Enabling this print statement causes the app to continue
// print(faces.count)
scnGeometry = SCNGeometry(sources: [verticesSource], elements: [facesElement])
}
func node(material: Any) -> SCNNode {
let scnMaterial = SCNMaterial()
scnMaterial.diffuse.contents = material
let geometry = scnGeometry
geometry.materials = [scnMaterial]
return SCNNode(geometry: geometry)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment