8

I'm experimenting with the vertical plane, and I'm trying to place a node on a wall with the correct rotation based on that vertical plane.

here's the ARHitTestResult of the vertical plane that gets tapped:

let hitLocation = sceneView.hitTest(touchPoint, types: .existingPlaneUsingExtent)

I've tried the following:

let hitRotation = hitLocation.first?.worldTransform.columns.2

and

let anchor = hitLocation.first?.anchor
let hitRotation = anchor?.transform.columns.2

neither one of them seem to work.

And this is what I'm hoping to do:

boardNode.eulerAngles = SCNVector3((hitRotation?.x)!, (hitRotation?.y)!, 0)

I'd much appreciate it if someone could help me out with this as I can't find a lot of tutorials on ARKit yet.

EDIT

so here's what worked (thanks to Josh):

let hit = sceneView.hitTest(touchPoint, types: .existingPlaneUsingExtent)
let planeAnchor = hit.first?.anchor as? ARPlaneAnchor

guard let anchoredNode =  sceneView.node(for: planeAnchor!) else { return }

let anchorNodeOrientation = anchoredNode.worldOrientation

boardNode.eulerAngles.y = .pi * anchorNodeOrientation.y

Note: .worldOrientation is way more accurate than .rotation in this case, just wanted to mention this.

LeftyT
  • 512
  • 6
  • 12

1 Answers1

6

Is this what your looking for? Here I am using the screen center for the CGPoint value, but you can use touch etc:

func addObjectToScreen() {

        if let hit = self.sceneView?.hitTest(self.viewCenter, types: [.existingPlaneUsingExtent]).last {

            let hitTestTransform = SCNMatrix4(hit.worldTransform)

            let vector = SCNVector3Make(hitTestTransform.m41, hitTestTransform.m42, hitTestTransform.m43)

            node.position = vector

            return
        }
}

Update: If you want to rotation of the node associated with the Plane couldn't you could get it like so:

 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {

      print(node.rotation)

}

Then use it as you need?

Further Update:

   override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

 /*
 1. Get The Current Touch Location
 2. Check That We Have Touched A Valid Node
 3. Check That Our Touched Object Is An ARPlane Anchor
 */

 guard let touchLocation = touches.first?.location(in: augmentedRealityView),
 let hitTest = augmentedRealityView.hitTest(touchLocation, types: .existingPlaneUsingExtent).first,
 let planeAnchor = hitTest.anchor as? ARPlaneAnchor
 else {

 // No Valid Plane Has Been Detected So Hide The Plane Information Label

 return

 }

    //We Have A Valid Plane So Display It's Current Info
    guard let anchoredNode =  augmentedRealityView.node(for: planeAnchor) else { return }
    print(anchoredNode.rotation)

 }
BlackMirrorz
  • 7,217
  • 2
  • 20
  • 31
  • this code places the node to the right location, but not the rotation though. in my case, I'm trying to update the Eulers of the node so that the node will be aligned to the vertical plane. – LeftyT Feb 27 '18 at 15:22
  • Could you not get the rotation of the node associated with the plane? I will update the answer above. – BlackMirrorz Feb 27 '18 at 15:31
  • thanks for the update, but this app detects multiple planes, so I'm trying to get the rotation of only the tapped plane. I believe that method gets called only when the plane node is added to the scene. – LeftyT Feb 27 '18 at 16:02
  • 1
    Posted my final attempt :) – BlackMirrorz Feb 27 '18 at 16:13