How to Attach an Object to Your Camera Position with Arkit Swift

How do you attach an object to your camera position with ARKit Swift?

In SceneKit, everything that can have a position in the scene is (attached to) a node. That includes not just visible objects, but also light sources and cameras. When you use ARSCNView, there's still a SceneKit camera, but ARKit controls its position/orientation.

SceneKit nodes create a hierarchy: every node's position (and orientation etc) are relative to its parent node. If the parent node moves within the scene, its children move along with it so that they keep the same parent-relative positions. So, if you want something to always keep the same position relative to the camera, you should make that content a child of the camera node.

Even in scenes where you don't create a camera yourself — such as when SceneKit and ARKit manage the camera for you — you can get the node containing the current camera with the view's pointOfView property. (Note: ARSCNView is a subclass of SCNView, most of whose useful API is defined by the SCNSceneRenderer protocol.)

You may have to wait until the session starts running to access the ARKit-managed camera node.

Position object in front of camera in RealityKit

First, add forward in an extension to float4x4 that gives the forward-facing directional vector of a transform matrix.

extension float4x4 {
var forward: SIMD3<Float> {
normalize(SIMD3<Float>(-columns.2.x, -columns.2.y, -columns.2.z))
}
}

Then, implement the following 4 steps:

func updateCursorPosition() {

let cameraTransform: Transform = arView.cameraTransform

// 1. Calculate the local camera position, relative to the sceneEntity
let localCameraPosition: SIMD3<Float> = sceneEntity.convert(position: cameraTransform.translation, from: nil)

// 2. Get the forward-facing directional vector of the camera using the extension described above
let cameraForwardVector: SIMD3<Float> = cameraTransform.matrix.forward

// 3. Calculate the final local position of the cursor using distanceFromCamera
let finalPosition: SIMD3<Float> = localCameraPosition + cameraForwardVector * distanceFromCamera

// 4. Apply the translation
cursorEntity.transform.translation = finalPosition

}

Scenekit move object with respect to camera

Here is the solution

guard let front = sceneView.pointOfView?.simdWorldFront else {return}
let horazontalRight = cross(front, simd_float3(0,1,0))

// for moving right
node.position += SCNVector3(horazontalRight * 0.01)

ARKit camera initial position?

To change the default orientation of your model, first select your model file from Xcode navigator then set camera Point of view to Front (from the bottom bar). This will show the exact view of your model when it is loaded in your scene.

Then, to change the position and orientation of the model, select the Node inspector from the right side menu (the cube icon) and change the Euler x, y, z values.

ARKit – Get current position of ARCamera in a scene

Set yourself as the ARSession.delegate. Than you can implement session(_:didUpdate:) which will give you an ARFrame for every frame processed in your session. The frame has an camera property that holds information on the cameras transform, rotation and position.

func session(_ session: ARSession, didUpdate frame: ARFrame) {
// Do something with the new transform
let currentTransform = frame.camera.transform
doSomething(with: currentTransform)
}

As rickster pointed out you always can get the current ARFrame and the camera position through it by calling session.currentFrame.
This is useful if you need the position just once, eg to move a node where the camera has been but you should use the delegate method if you want to get updates on the camera's position.



Related Topics



Leave a reply



Submit