import UIKit
import SceneKit
import ARKit
import PlaygroundSupport
class ViewController: UIViewController, ARSCNViewDelegate {
//Declaring what we may need
let configuration = ARWorldTrackingConfiguration()
let sceneView: ARSCNView = ARSCNView(frame: CGRect(x: 0, y: 0, width: 300, height: 600))
var drawBtn: UIButton {
let sampleBtn = UIButton(frame: CGRect(x: 170, y: 550, width: 100, height: 50))
sampleBtn.setTitle("Draw", for: .normal)
sampleBtn.setTitleColor(UIColor.black, for: .normal)
sampleBtn.backgroundColor = UIColor.white
return sampleBtn
}
//setting up our objects
override func viewDidLoad(){
super.viewDidLoad()
//setting up the scene view
self.sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints, ARSCNDebugOptions.showWorldOrigin]
self.sceneView.delegate = self
self.sceneView.showsStatistics = true
self.sceneView.session.run(configuration)
//adding our views as a subview to the main view
self.view.addSubview(sceneView)
self.view.addSubview(drawBtn)
}
//the renderer function
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.drawBtn.isHighlighted {
let sphereNode = SCNNode(geometry: SCNSphere(radius: 0.02))
sphereNode.position = currentPositionOfCamera
self.sceneView.scene.rootNode.addChildNode(sphereNode)
sphereNode.geometry?.firstMaterial?.diffuse.contents = UIColor.red
//print("draw button is being pressed")
}
else {
let pointer = SCNNode()
pointer.geometry = SCNSphere(radius: 0.01)
pointer.name = "pointer"
pointer.position = currentPositionOfCamera
self.sceneView.scene.rootNode.enumerateChildNodes({ (myNode, _) in
if myNode.name == "pointer" {
myNode.removeFromParentNode()
}
})
self.sceneView.scene.rootNode.addChildNode(pointer)
pointer.geometry?.firstMaterial?.diffuse.contents = UIColor.red
}
}
}
}
//Modifying the + so that it can add two SCNVector3
func +(left: SCNVector3, right: SCNVector3) -> SCNVector3 {
return SCNVector3Make(left.x + right.x, left.y + right.y, left.z + right.z)
}
let vc = ViewController()
vc.preferredContentSize = CGSize(width: 1080, height: 1920)
PlaygroundPage.current.liveView = vc
PlaygroundPage.current.needsIndefiniteExecution = true
Hey there! I am running the code above on my iPad in the swift playgrounds app. However once I run this, it says: "There was a problem encountered while running this playground. Check your code for mistakes". On stepping through my code, on line 30, it says - "BUG IN CLIENT OF LIBDISPATCH: dispatch_sync called on queue already owned by current thread". What may be the error and how to fix it? Please also suggest me some ways to prevent these errors in future.