How to Set a Known Position and Orientation as a Starting Point of Arkit

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.

How to make Text to have the same position and orientation as Box?

It's easy. Just make a text to be a child of cube and pin that cube with anchor. In ECS frameworks child always copy from its parent position, orientation and scale.

let box = MeshResource.generateBox(size: 1)
let boxEntity = ModelEntity(mesh: box)

let anchor = AnchorEntity()
boxEntity.setParent(anchor)
arView.scene.addAnchor(anchor)

let text = MeshResource.generateText("AR",
extrusionDepth: 0.01,
font: .systemFont(ofSize: 0.25),
containerFrame: .zero,
alignment: .center,
lineBreakMode: .byWordWrapping)

let shader = UnlitMaterial(color: .yellow)
let textEntity = ModelEntity(mesh: text, materials: [shader])
textEntity.position.z += 0.6

// Changing a position, orientation and scale of the parent
boxEntity.addChild(textEntity)
boxEntity.transform = Transform(pitch: .pi/8, yaw: .pi/8, roll: .pi/8)
boxEntity.position.x = -0.5
boxEntity.scale /= 2

Now child always follows his parent.

Sample Image

How can I set text orientation in ARKit?

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.

ARKit vs ARCore - Orientation

Technically and conceptually, both approaches are the same. Contrary to what the article says,

interprets IMU (Inertial Measurement Unit) data unlike ARKit that goes with VIO

ARKit interprets image features (Visual) and IMU data (Inertial) and fuses them to get the change in position over time (Odometry) -> Visual inertial Odometry

ARCore interprets image features and IMU data and fuses them to get the change in position over time -> Visual Inertial Odometry

So the approaches and underlying concepts are the same. What differs is the implementation. I think it is just a decision to be made what to do if the visual part of the tracking system fails. Apple seems to have decided to still use the IMU (which can still track the orientation) while Google decided to stop the whole tracking framework (Maybe you have noticed, that after you cover the ARCore camera, you have around 1 second in which the tracking reacts to orientation changes. It is only after a timeout, that the tracking stops completely)

Unity ARKit SetWorldOrigin - Wrong Rotation

Okay, finally I found another solution. Instead of changing the WorldOrigin with ARKit, I made all my 3D objects as child objects of an empty GameObject. Then I changed this GameObject with my correction values (translation and rotation).

Which measuring unit is used in SCNVector3 position for x, y and z in ARKit

In ARKit the unit of measurement is in Meters.

Sample Image

When you launch your ARKit app, the worldOrigin is set at SCNVector3Zero which is (0,0,0) (or in the diagram where the X,Y,Z axis intersect):

ARKit defines a world coordinate space for you to use to place virtual
content and locate detected objects in an AR experience. By default,
this space is based on the initial position and orientation of the
device when the session begins.

An SCNVector3 is simply:

a three-component vector which is used for a variety of purposes, such
as describing node or vertex positions, surface normals, and scale or
translation transforms. The different vector components should be
interpreted based on the context in which the vector is being used.

So each part corresponds to the X, Y and Z values e.g:

let position = SCNVector3 (x, y, z)

Given your position var you are saying that you want to place the object centrally in regard to the worldOrigin and 2meters away from the camera.

Hope it helps...

Persist object orientations in ARKit ARWorldMap

Apple Documentation for ARWorldMap shows that the properties for an ARWorldMap class are:
<code>anchors: [ARAnchor]</code>, <code>center: simd_float3</code>, and <code>extent: simd_float3</code>

When you archive a world map, these are the only information that get saved. Any information about the nodes added to the anchors during the session (e.g. changing node scale and orientation) are not saved along with the world map during the archiving.

I remember watching a WWDC session where they demoed a multiplayer AR game called SwiftShot where players hit different objects with balls. They provided the source code and I noticed they used a custom ARAnchor subclass called BoardAnchor which they used to store additional information in the anchor class such as the size of the game board.
See: SwiftShot: Creating a Game for Augmented Reality.

You can use the same approach to store, for example, the scale and orientation of a node, so that when you unarchive the world map and it get's relocalized, you can use ARSCNViewDelegate's renderer(_:didAdd:for:) to resize and scale the node based on the information stored in your custom ARAnchor.



Related Topics



Leave a reply



Submit