Press ESC to close

Drawing with ARKit

Hello friends, in this article, we will talk about how to draw with Swift ARKit. You can find my previous post here.

We need to create a project and do the same things we did in our previous articles. After adding SceneKit in the Design section, let’s put a button to start drawing and the drawing process will start after the user presses this button. After we’re done with the design, we need to bind it to the ViewController.

Then, every time the ARKit scene is rendered, we need to process it here. We need to bind its delegate so that we can catch it when it renders. I’ve been providing this with an Extension. Then I need to get the coordinates of the midpoint of the screen. After obtaining this information, if the user presses the button, I will put a dot every time he renders to the screen. I will put a pink pointer to show the middle point of the screen to the user if the button is not pressed. When the user presses the button, this pointer will disappear and drawing will begin.

//
//  ViewController.swift
//  arkit-drawing
//
//  Created by Omer Sezer on 9.07.2021.
//

import UIKit
import ARKit

class ViewController: UIViewController {

    @IBOutlet weak var sceneView: ARSCNView!
    @IBOutlet weak var btnDraw: UIButton!
    let configuration = ARWorldTrackingConfiguration()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUI()
    }

    func setUI() {
        // MARK: sceneView
        sceneView.debugOptions = [.showWorldOrigin, .showFeaturePoints]
        sceneView.showsStatistics = true
        sceneView.delegate = self
        sceneView.session.run(configuration)
    }
}

extension ViewController: ARSCNViewDelegate {
    func renderer(_ renderer: SCNSceneRenderer, willRenderScene scene: SCNScene, atTime time: TimeInterval) {
        guard let pointOfView = sceneView.pointOfView else { return }
        let transform = pointOfView.transform
        let orientation = SCNVector3(-transform.m31, -transform.m32, -transform.m33)
        let location = SCNVector3(transform.m41, transform.m42, transform.m43)
        let currentPositionOfCamera = orientation + location
        DispatchQueue.main.async {
            if self.btnDraw.isHighlighted {
                let nodeSphere = SCNNode(geometry: SCNSphere(radius: 0.02))
                nodeSphere.position = currentPositionOfCamera
                self.sceneView.scene.rootNode.addChildNode(nodeSphere)
                nodeSphere.geometry?.firstMaterial?.diffuse.contents = UIColor.green
            } else {
                let pointer = SCNNode(geometry: SCNSphere(radius: 0.01))
                pointer.name = "pointer"
                pointer.position = currentPositionOfCamera
                self.sceneView.scene.rootNode.enumerateChildNodes { node, _ in
                    if node.name == "pointer" {
                        node.removeFromParentNode()
                        
                    }
                }
                self.sceneView.scene.rootNode.addChildNode(pointer)
                pointer.geometry?.firstMaterial?.diffuse.contents = UIColor.systemPink
            }
        }
    }
}

func +(left: SCNVector3, right: SCNVector3) -> SCNVector3 {
    return SCNVector3(x: left.x + right.x, y: left.y + right.y, z: left.z + right.z)
}

The screen output of the project is as follows.

 

You can access the project here. If you have questions, you can reach us by sending an e-mail or comment. Good work.

 

Leave a Reply

Your email address will not be published. Required fields are marked *