Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I set text orientation in ARKit?

Tags:

ios

swift

arkit

I am creating a simple app with ARKit in which I add some text to the scene to the tapped position:

@objc func tapped(sender: UITapGestureRecognizer){
    let sceneView = sender.view as! ARSCNView
    let tapLocation = sender.location(in: sceneView)
    let hitTest = sceneView.hitTest(tapLocation, types: .featurePoint)
    if !hitTest.isEmpty{
        self.addTag(tag: "A", hitTestResult: hitTest.first!)
    }
    else{
        print("no match")
    }
}

func addTag(tag: String, hitTestResult: ARHitTestResult){
    let tag = SCNText(string:tag, extrusionDepth: 0.1)
    tag.font = UIFont(name: "Optima", size: 1)
    tag.firstMaterial?.diffuse.contents = UIColor.red

    let tagNode = SCNNode(geometry: tag)

    let transform = hitTestResult.worldTransform
    let thirdColumn = transform.columns.3
    tagNode.position = SCNVector3(thirdColumn.x,thirdColumn.y - tagNode.boundingBox.max.y / 2,thirdColumn.z)
    print("\(thirdColumn.x) \(thirdColumn.y) \(thirdColumn.z)")
    self.sceneView.scene.rootNode.addChildNode(tagNode)
}

It works, but I have problem with the orientation of the text. When I add it with the camera's original position, the text orientation is ok, I can see the text frontwise (Sample 1). But when I turn camera to the left / right, and add the text by tapping, I can see the added text from the side (Sample 2).

Sample 1:

3-D letter from the front

Sample 2:

3-D letter from the side

I know there should be some simple trick to solve it, but as a beginner in this topic I could not find it so far.

like image 452
Tom Avatar asked Oct 25 '17 13:10

Tom


2 Answers

You want the text to always face the camera? SCNBillboardConstraint is your friend:

tagNode.constraints = [SCNBillboardConstraint()]
like image 74
rickster Avatar answered Nov 05 '22 23:11

rickster


Am I correct in saying that you want the text to face the camera when you tap (wherever you happen to be facing), but then remain stationary?

There are a number of ways of adjusting the orientation of any node. For this case I would suggest simply setting the eulerAngles of the text node to be equal to those of the camera, at the point in which you instantiate the text.

In your addTag() function you add:

let eulerAngles = self.sceneView.session.currentFrame?.camera.eulerAngles
tagNode.eulerAngles = SCNVector3(eulerAngles.x, eulerAngles.y, eulerAngles.z + .pi / 2)

The additional .pi / 2 is there to ensure the text is in the correct orientation, as the default with ARKit is for a landscape orientation and therefore the text comes out funny. This applies a rotation around the local z axis.

It's also plausible (and some may argue it's better) to use .localRotate() of the node, or to access its transform property, however I like the approach of manipulating both the position and eulerAngles directly.

Hope this helps.

EDIT: replaced Float(1.57) with .pi / 2.

like image 20
Jordan Avatar answered Nov 06 '22 00:11

Jordan