Skip to content

Instantly share code, notes, and snippets.

@digitallysavvy
Last active December 1, 2019 06:04
Show Gist options
  • Select an option

  • Save digitallysavvy/d78783f8d886d20d26356d70c386cb1b to your computer and use it in GitHub Desktop.

Select an option

Save digitallysavvy/d78783f8d886d20d26356d70c386cb1b to your computer and use it in GitHub Desktop.

Revisions

  1. digitallysavvy revised this gist Dec 1, 2019. 1 changed file with 20 additions and 20 deletions.
    40 changes: 20 additions & 20 deletions ARViewController.swift
    Original file line number Diff line number Diff line change
    @@ -33,26 +33,6 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate, ARSessionD
    // set reference to sceneView
    self.sceneView = sceneView
    }

    override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // Configure ARKit Session
    let configuration = ARWorldTrackingConfiguration() // ARKit trackign configuration
    configuration.planeDetection = [.horizontal, .vertical]
    configuration.providesAudioData = true // enable audio data
    configuration.isLightEstimationEnabled = true // enable light estimation (save on processing)

    self.sceneView.session.run(configuration) // set cunfiguration for ARKit session
    }

    override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // Pause the view's session
    self.sceneView.session.pause()
    self.sceneView.removeFromSuperview()
    self.sceneView = nil
    }

    override func viewDidLoad() {
    super.viewDidLoad()
    @@ -67,13 +47,33 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate, ARSessionD
    }
    }

    override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // Configure ARKit Session
    let configuration = ARWorldTrackingConfiguration() // ARKit trackign configuration
    configuration.planeDetection = [.horizontal, .vertical]
    configuration.providesAudioData = true // enable audio data
    configuration.isLightEstimationEnabled = true // enable light estimation (save on processing)

    self.sceneView.session.run(configuration) // set cunfiguration for ARKit session
    }

    override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    let light = self.createLight(withPosition: SCNVector3(x: 0,y: 5,z: 0), andEulerRotation: SCNVector3(-Float.pi / 2, 0, 0))
    self.sceneView.scene.rootNode.addChildNode(light)
    self.scnLights.append(light)
    }

    override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // Pause the view's session
    self.sceneView.session.pause()
    self.sceneView.removeFromSuperview()
    self.sceneView = nil
    }

    // MARK: Hide status bar
    override var prefersStatusBarHidden: Bool {
    return true
  2. digitallysavvy revised this gist Dec 1, 2019. 1 changed file with 3 additions and 2 deletions.
    5 changes: 3 additions & 2 deletions ARViewController.swift
    Original file line number Diff line number Diff line change
    @@ -35,9 +35,10 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate, ARSessionD
    }

    override func viewWillAppear(_ animated: Bool) {
    super .viewWillAppear(animated)
    super.viewWillAppear(animated)
    // Configure ARKit Session
    let configuration = ARWorldTrackingConfiguration() // ARKit trackign configuration
    configuration.planeDetection = [.horizontal, .vertical]
    configuration.providesAudioData = true // enable audio data
    configuration.isLightEstimationEnabled = true // enable light estimation (save on processing)

    @@ -61,7 +62,7 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate, ARSessionD
    self.sceneView.session.delegate = self

    if debug {
    self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints]
    self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints, .showBoundingBoxes]
    self.sceneView.showsStatistics = true
    }
    }
  3. digitallysavvy revised this gist Dec 1, 2019. 1 changed file with 56 additions and 20 deletions.
    76 changes: 56 additions & 20 deletions ARViewController.swift
    Original file line number Diff line number Diff line change
    @@ -8,15 +8,17 @@
    import UIKit
    import ARKit

    internal class ARViewController: UIViewController, ARSCNViewDelegate {
    internal class ARViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate {

    var sceneView : ARSCNView!
    var scnLights : [SCNNode] = []

    let debug : Bool = true // toggle the debug logs

    let debug : Bool = false

    // MARK: VC Events
    override func loadView() {
    super.loadView()
    self.view.backgroundColor = UIColor.black // set the background color

    // Setup sceneview
    let sceneView = ARSCNView() //instantiate scene view
    @@ -33,32 +35,33 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate {
    }

    override func viewWillAppear(_ animated: Bool) {
    super .viewWillAppear(animated)
    // Configure ARKit Session
    let configuration = ARWorldTrackingConfiguration()
    if #available(iOS 11.3, *) {
    configuration.planeDetection = [.horizontal, .vertical]
    } else {
    // Fallback on earlier versions
    configuration.planeDetection = [.horizontal]
    }
    configuration.isLightEstimationEnabled = true
    let configuration = ARWorldTrackingConfiguration() // ARKit trackign configuration
    configuration.providesAudioData = true // enable audio data
    configuration.isLightEstimationEnabled = true // enable light estimation (save on processing)

    self.sceneView.session.run(configuration)
    self.sceneView.session.run(configuration) // set cunfiguration for ARKit session
    }

    override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // Pause the view's session
    self.sceneView.session.pause()
    self.sceneView.removeFromSuperview()
    self.sceneView = nil
    }

    override func viewDidLoad() {
    super.viewDidLoad()

    // set render delegate
    // set ARKit render and session delegates
    self.sceneView.delegate = self
    self.sceneView.session.delegate = self

    if debug {
    self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, .showBoundingBoxes, ARSCNDebugOptions.showFeaturePoints]
    self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, ARSCNDebugOptions.showFeaturePoints]
    self.sceneView.showsStatistics = true
    }
    }
    @@ -70,16 +73,13 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate {
    self.scnLights.append(light)
    }

    // hide the status bar
    // MARK: Hide status bar
    override var prefersStatusBarHidden: Bool {
    return true
    }

    // renderer delegate methods
    // MARK: Render delegate
    func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {

    // TODO: Add config option to enable/disable real-world lighting
    // change the .intensity property of scene env light to they respond to the real world env
    guard let currentFrame = self.sceneView.session.currentFrame else { return }
    let intensity : CGFloat = currentFrame.lightEstimate!.ambientIntensity / 1000.0
    self.sceneView.scene.lightingEnvironment.intensity = intensity
    @@ -88,12 +88,18 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate {
    node.light?.intensity = intensity
    }
    }

    // do something when scene will render
    }

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    // do something on render update
    }

    func renderer(_ renderer: SCNSceneRenderer, didRenderScene scene: SCNScene, atTime time: TimeInterval) {

    }

    // plane detection
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    // anchor plane detection
    @@ -108,6 +114,35 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate {
    // anchor plane is removed
    }

    // MARK: Session delegate
    func session(_ session: ARSession, didUpdate frame: ARFrame) {
    // ARSession did update
    }

    func session(_ session: ARSession, didOutputAudioSampleBuffer audioSampleBuffer: CMSampleBuffer) {
    // ARSession did output audio data
    }

    func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) {
    // ARSession camera tracking state change
    }

    func sessionWasInterrupted(_ session: ARSession) {
    // ARSession was interrupted
    }

    func sessionInterruptionEnded(_ session: ARSession) {
    // ARSession interuption ended
    }

    func sessionShouldAttemptRelocalization(_ session: ARSession) -> Bool {
    // whether to attempt recovery of world-tracking state after an interruption.
    return true
    }



    // MARK: Lights
    func createLight(withPosition position: SCNVector3, andEulerRotation rotation: SCNVector3) -> SCNNode {
    // Create a directional light node with shadow
    let directionalNode : SCNNode = SCNNode()
    @@ -120,10 +155,11 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate {
    directionalNode.light?.shadowRadius = 16
    directionalNode.light?.shadowMode = .deferred
    directionalNode.light?.shadowMapSize = CGSize(width: 1024, height: 1024)
    directionalNode.light?.shadowColor = UIColor.black.withAlphaComponent(0.75)
    directionalNode.light?.shadowColor = UIColor.black.withAlphaComponent(0.5)
    directionalNode.position = position
    directionalNode.eulerAngles = rotation

    return directionalNode
    }

    }
  4. digitallysavvy revised this gist Oct 30, 2019. 1 changed file with 1 addition and 6 deletions.
    7 changes: 1 addition & 6 deletions ARViewController.swift
    Original file line number Diff line number Diff line change
    @@ -75,7 +75,7 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate {
    return true
    }

    // render delegate methods
    // renderer delegate methods
    func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {

    // TODO: Add config option to enable/disable real-world lighting
    @@ -89,11 +89,6 @@ internal class ARViewController: UIViewController, ARSCNViewDelegate {
    }
    }
    }

    // scene rendering
    func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
    // do something just before scene renders
    }

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    // do something on render update
  5. digitallysavvy created this gist Oct 29, 2019.
    134 changes: 134 additions & 0 deletions ARViewController.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,134 @@
    //
    // ARViewController.swift
    //
    // Created by digitallysavvy.
    // Copyright © 2019 digitallysavvy All rights reserved.
    //

    import UIKit
    import ARKit

    internal class ARViewController: UIViewController, ARSCNViewDelegate {

    var sceneView : ARSCNView!
    var scnLights : [SCNNode] = []

    let debug : Bool = false

    override func loadView() {
    super.loadView()

    // Setup sceneview
    let sceneView = ARSCNView() //instantiate scene view
    self.view.insertSubview(sceneView, at: 0)

    //add sceneView layout contstraints
    sceneView.translatesAutoresizingMaskIntoConstraints = false
    sceneView.topAnchor.constraint(equalTo: self.view.topAnchor).isActive = true
    sceneView.leftAnchor.constraint(equalTo: self.view.leftAnchor).isActive = true
    sceneView.rightAnchor.constraint(equalTo: self.view.rightAnchor).isActive = true
    sceneView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
    // set reference to sceneView
    self.sceneView = sceneView
    }

    override func viewWillAppear(_ animated: Bool) {
    // Configure ARKit Session
    let configuration = ARWorldTrackingConfiguration()
    if #available(iOS 11.3, *) {
    configuration.planeDetection = [.horizontal, .vertical]
    } else {
    // Fallback on earlier versions
    configuration.planeDetection = [.horizontal]
    }
    configuration.isLightEstimationEnabled = true

    self.sceneView.session.run(configuration)
    }

    override func viewWillDisappear(_ animated: Bool) {
    // Pause the view's session
    self.sceneView.session.pause()
    }

    override func viewDidLoad() {
    super.viewDidLoad()

    // set render delegate
    self.sceneView.delegate = self

    if debug {
    self.sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin, .showBoundingBoxes, ARSCNDebugOptions.showFeaturePoints]
    self.sceneView.showsStatistics = true
    }
    }

    override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    let light = self.createLight(withPosition: SCNVector3(x: 0,y: 5,z: 0), andEulerRotation: SCNVector3(-Float.pi / 2, 0, 0))
    self.sceneView.scene.rootNode.addChildNode(light)
    self.scnLights.append(light)
    }

    // hide the status bar
    override var prefersStatusBarHidden: Bool {
    return true
    }

    // render delegate methods
    func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {

    // TODO: Add config option to enable/disable real-world lighting
    // change the .intensity property of scene env light to they respond to the real world env
    guard let currentFrame = self.sceneView.session.currentFrame else { return }
    let intensity : CGFloat = currentFrame.lightEstimate!.ambientIntensity / 1000.0
    self.sceneView.scene.lightingEnvironment.intensity = intensity
    if scnLights.count > 0 {
    for node in scnLights {
    node.light?.intensity = intensity
    }
    }
    }

    // scene rendering
    func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
    // do something just before scene renders
    }

    func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
    // do something on render update
    }

    // plane detection
    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    // anchor plane detection
    }

    // plane updating
    func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    // anchor plane is updated
    }

    func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {
    // anchor plane is removed
    }

    func createLight(withPosition position: SCNVector3, andEulerRotation rotation: SCNVector3) -> SCNNode {
    // Create a directional light node with shadow
    let directionalNode : SCNNode = SCNNode()
    directionalNode.light = SCNLight()
    directionalNode.light?.type = SCNLight.LightType.directional
    directionalNode.light?.color = UIColor.white
    directionalNode.light?.castsShadow = true
    directionalNode.light?.automaticallyAdjustsShadowProjection = true
    directionalNode.light?.shadowSampleCount = 64
    directionalNode.light?.shadowRadius = 16
    directionalNode.light?.shadowMode = .deferred
    directionalNode.light?.shadowMapSize = CGSize(width: 1024, height: 1024)
    directionalNode.light?.shadowColor = UIColor.black.withAlphaComponent(0.75)
    directionalNode.position = position
    directionalNode.eulerAngles = rotation

    return directionalNode
    }
    }