I have an SCNNode(nodeObj) added in an ARSCNView(sceneView) :
let config = ARWorldTrackingConfiguration()
config.planeDetection = [.horizontal]
self.sceneView.delegate = self
self.sceneView.session.run(config)
self.sceneView.autoenablesDefaultLighting = true
self.sceneView.automaticallyUpdatesLighting = true
let antennaScene = SCNScene(named: sceneName)
guard let antennaNode = antennaScene?.rootNode.childNode(withName: antennaNodeName,
recursively: true)
else { fatalError("no model found!") }
antennaNode.position = SCNVector3(x: 0.0, y: 0.0, z: -5.0)
antennaNode.scale = SCNVector3(0.002, 0.002, 0.002)
self.sceneView.scene.rootNode.addChildNode(antennaNode)
Update :
extension ARViewController: ARSCNViewDelegate {
func addPlane(node: SCNNode, anchor: ARPlaneAnchor) {
let plane = Plane(anchor)
planes[anchor] = plane
plane.setPlaneVisibility(self.setPlaneVisibility)
node.addChildNode(plane)
NSLog("Added plane: \(plane)")
}
func updatePlane(anchor: ARPlaneAnchor) {
if let plane = planes[anchor] {
plane.update(anchor)
}
}
func removePlane(anchor: ARPlaneAnchor) {
NSLog("In removePlane :")
if let plane = planes.removeValue(forKey: anchor) {
plane.removeFromParentNode()
}
}
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
NSLog("In didAdd:")
if let planeAnchor = anchor as? ARPlaneAnchor {
self.addPlane(node: node, anchor: planeAnchor)
if !self.sceneRendered {
self.sceneRendered = true
self.selectedModel.scale = SCNVector3(0.001, 0.001, 0.001)
self.selectedModel.position = SCNVector3Zero
node.addChildNode(self.selectedModel)
}
}
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
NSLog("In didUpdate:")
DispatchQueue.main.async {
if let planeAnchor = anchor as? ARPlaneAnchor {
self.updatePlane(anchor: planeAnchor)
}
}
}
//MARK: Gesture Handling Methods
//This method enables multiple gestures recognizor settings
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer,
shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer)
-> Bool {
return true
}
//Move Antenna across the screen
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
NSLog("In touchesMoved : ")
NSLog("In touchesMoved:")
guard (self.selectedModel != nil) else {
NSLog("In touches Moved : No Antenna added to the screen")
return
}
//If touches is 2 then its pinch gesture for scaling. If touches is 1 then its pan gesture for antenna movement
guard touches.count <= 1 else {
NSLog("In touches Moved : returned")
return
}
//1. Get The Current Touch Point
guard let currentTouchPoint = touches.first?.location(in: self.sceneView),
//2. Get The Existing ARPlaneAnchor
let hitTest = self.sceneView.hitTest(currentTouchPoint, types: .existingPlane).first else { return }
//3. Convert To World Coordinates
let worldTransform = hitTest.worldTransform
//4. Set The New Position
let newPosition = SCNVector3(worldTransform.columns.3.x, worldTransform.columns.3.y, worldTransform.columns.3.z)
//5. Apply To The Node
/*!!AFTER THIS LINE EXECUTION MOVEMENT STARTS!!*/
self.selectedModel.position = SCNVector3(SIMD3(x: newPosition.x, y: newPosition.y, z: newPosition.z))
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
NSLog("In touchesEnded :")
self.setPlaneVisibility = false
for anchor in planes {
if let planeAnchor = anchor.key as? ARPlaneAnchor {
removePlane(anchor: planeAnchor)
}
}
}
NOTE: When I set position in touchesMoved method, node starts moving with device.
I have set its position as well. But if I move my iPhone / iPad, the node moves as well. I need the node to be anchored at a single position and not move as device moves.
Any help would be great. Thanks in advance!
//5. Apply To The Node /!!AFTER THIS LINE EXECUTION MOVEMENT STARTS!!/ self.selectedModel.position = SCNVector3(SIMD3(x: newPosition.x, y: newPosition.y, z: newPosition.z))
In stead of changing self.selectedModel.position I updated the code to self.selectedModel.worldPosition