1
votes

I'm currently programming an AR-App, which starts with placing a SCNNode (table). First the app searches for a horizontal plane and whenever a surface was found, the object is shown, but not placed yet. While it is not placed, I want the object to face the camera at all times, but I'm having trouble to find the current position of the camera and also updating the object every frame.

Currently, the object is facing the world coordinates. So when I start the app and a horizontal plane was found - the object appears and faces to the starting point of the world coordinates (wherever I started the app)

Can anybody help me, how to get the vector from the camera position and make the object updates it's direction every frame?

var tableNode : SCNNode!  // Node of the actual table

var trackingPosition = SCNVector3Make(0.0, 0.0, 0.0)

let trans = SCNMatrix4(hitTest.worldTransform)

self.trackingPosition = SCNVector3Make(trans.m41, trans.m42, trans.m43)

self.tableNode.position = self.trackingPosition
2

2 Answers

0
votes

The functionality you are trying to implement is called billboarding. To achieve this effect you need to set the SCNLookAtConstraint using the scene's .pointOfView as the target.

you can remove

self.trackingPosition = SCNVector3Make(trans.m41, trans.m42, trans.m43)
self.tableNode.position = self.trackingPosition

and use:

// set constraint to force the node to always face camera
let constraint = SCNLookAtConstraint(target:sceneView.pointOfView)
constraint.isGimbalLockEnabled = true
self.tableNode.constraints = [constraint] // constraint can cause node appear flipped over X axis
0
votes

You should implement ARSCNViewDelegate and use the renderer method renderer(_:updateAtTime:) where you every frame get the camera position from sceneView.pointOfView. This allows you to then use the SCNNode method look(at:) to transform the nodes coordinate system towards the camera.

func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
        if let camera = sceneView.pointOfView {
           tableNode.look(at: camera.worldPosition)
        }
}