8
votes

The code below places a SCNPlane onto the point touched, but the plane is oriented (rotated) to the position that the phone was in when the app started. I would ideally like to orient the Node to a physical wall or to the current orientation of the camera. How is this done with ARKit?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else {return}
    let result = sceneView.hitTest(touch.location(in: sceneView), types: [ARHitTestResult.ResultType.featurePoint])
    guard let hitResult = result.last else {return}
    let hitTransform = SCNMatrix4.init(hitResult.worldTransform)

    let hitVector = SCNVector3Make(hitTransform.m41, hitTransform.m42, hitTransform.m43)
    createPlane(position: hitVector)
}

func createPlane(position: SCNVector3) {

    let background = SCNNode()
    background.geometry = SCNPlane.init(width: 0.12, height: 0.10) // better set its size
    background.geometry?.firstMaterial?.diffuse.contents = "odinBW2.jpeg"
    background.position = position

    sceneView.scene.rootNode.addChildNode(background)

}
2
did you find any solution for it??Aatish Rajkarnikar
In the end I decided to prepare the user with instructions to face the phone in the proper direction before starting the arkit view.Rob Schlackman

2 Answers

10
votes

If you want to align your node to the camera's orientation, just use SCNBillboardConstraint.

let yourNode = SCNNode()

let billboardConstraint = SCNBillboardConstraint()
billboardConstraint.freeAxes = [.X, .Y, .Z]
yourNode.constraints = [billboardConstraint]
7
votes

1 - This is how you get the rotation of the camera first:

Pitch - rotation around the X axis

let pitch = sceneView.session.currentFrame?.camera.eulerAngles.x 

Yawn - rotation around the Y axis

let yawn = sceneView.session.currentFrame?.camera.eulerAngles.y

Roll - rotation around the Z axis

let roll = sceneView.session.currentFrame?.camera.eulerAngles.z

2 - And then you can create the SCNVector3 that matches the rotations you want to keep (0 if you don't want any rotation on an axis) :

let newRotation = SCNVector3Make(pitch, yawn, roll)

3 - And then you attribute this eulerAngles to your node:

whateverNode.eulerAngles = newRotation