My goal is to be able to move/rotate AR objects using the gestureRecognizer. While I got it working for a single AR cube, I cannot get it work for multiple cubes/objects.
Main part of the viewDidLoad:
let boxNode1 = addCube(position: SCNVector3(0,0,0), name: "box")
let boxNode2 = addCube(position: SCNVector3(0,-0.1,-0.1), name: "box2")
sceneView.scene.rootNode.addChildNode(boxNode1)
sceneView.scene.rootNode.addChildNode(boxNode2)
var nodes: [SCNNode] = getMyNodes()
var parentNode = SCNNode()
parentNode.name = "motherNode"
for node in nodes {
parentNode.addChildNode(node)
}
sceneView.scene.rootNode.addChildNode(parentNode)
// sceneView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(ViewController.handleTap(_:))))
sceneView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(ViewController.handleMove(_:))))
sceneView.addGestureRecognizer(UIRotationGestureRecognizer(target: self, action: #selector(ViewController.handleRotate(_:))))
let configuration = ARWorldTrackingConfiguration()
sceneView.session.run(configuration)
Part of panGesture (works for each cube, but does not work if I change to nodeHit.Parent!) The parent node is detected correctly, but no change is made to it:
@objc func handleMove(_ gesture: UIPanGestureRecognizer) {
//1. Get The Current Touch Point
let location = gesture.location(in: self.sceneView)
//2. Get The Next Feature Point Etc
guard let nodeHitTest = self.sceneView.hitTest(location, options: nil).first else { print("no node"); return }
var nodeHit = nodeHitTest.node
// nodeHit = nodeHit.parent!
//3. Convert To World Coordinates
let worldTransform = nodeHitTest.simdWorldCoordinates
//4. Apply To The Node
nodeHit.position = SCNVector3(worldTransform.x, worldTransform.y, 0)
}
What I want to do is to be able to move both cube at once (so they all undergoes the same translation). It sounds possible from this post: How to join multiple nodes to one node in iOS scene However, at the same time this post also says I cannot do that for reason I do not understand yet: SceneKit nodes aren't changing position with scene's root node In the worst case I think it is possible to manually apply the transformation to every child node, however applying translation to one parent Node seems to be a much elegant way for doing this.
Edit: I tried this way and can get both moving nodes moving, however sometimes the position is reversed (sometimes the cube comes on top of the other when they should not):
@objc func handleMove(_ gesture: UIPanGestureRecognizer) {
//1. Get The Current Touch Point
let location = gesture.location(in: self.sceneView)
//2. Get The Next Feature Point Etc
guard let nodeHitTest = self.sceneView.hitTest(location, options: nil).first else { print("no node"); return }
// var nodeHit = nodeHitTest.node
let nodeHit = nodeHitTest.node
let original_x = nodeHitTest.node.position.x
let original_y = nodeHitTest.node.position.y
print(original_x, original_y)
// let nodeHit = sceneView.scene.rootNode.childNode(withName: "motherNode2", recursively: true)
//3. Convert To World Coordinates
let worldTransform = nodeHitTest.simdWorldCoordinates
//4. Apply To The Node
//// nodeHit.position = SCNVector3(worldTransform.x, worldTransform.y, 0)
nodeHit.position = SCNVector3(worldTransform.x, worldTransform.y, 0)
for node in nodeHit.parent!.childNodes {
if node.name != nil{
if node.name != nodeHit.name {
let old_x = node.position.x
let old_y = node.position.y
print(old_x, old_y)
node.position = SCNVector3((nodeHit.simdPosition.x + original_x - old_x), (nodeHit.simdPosition.y + original_y - old_y), 0)
}
}
}
Any ideas?