How to Calculate a Distance Between Two Anchorentities

How can I calculate a distance between two AnchorEntities?

Theory

It's a bit tricky in RealityKit 2.0 . The position of the entity relative to its parent is:

public var position: SIMD3<Float>

// the same as: entity.transform.translation

But in your case, it doesn't work for AnchorEntity that has no parent. What actually does work is an instance method that returns a position of an entity relative to referenceEntity (even if it's nil, because nil implies a world space):

public func position(relativeTo referenceEntity: Entity?) -> SIMD3<Float>

Solution

import UIKit
import RealityKit

class ViewController: UIViewController {

@IBOutlet var arView: ARView!

let anchor_01 = AnchorEntity(world: [ 1.22, 1.47,-2.75])
let anchor_02 = AnchorEntity(world: [-2.89, 0.15, 1.46])

override func viewDidLoad() {
super.viewDidLoad()

arView.scene.anchors.append(anchor_01)
arView.scene.anchors.append(anchor_02)

let dst = distanceBetweenEntities(anchor_01.position(relativeTo: nil),
and: anchor_02.position(relativeTo: nil))

print("The distance is: \(dst)") // WORKS
print("The position is: \(anchor_01.position)") // doesn't work
}

private func distanceBetweenEntities(_ a: SIMD3<Float>,
and b: SIMD3<Float>) -> SIMD3<Float> {

var distance: SIMD3<Float> = [0, 0, 0]
distance.x = abs(a.x - b.x)
distance.y = abs(a.y - b.y)
distance.z = abs(a.z - b.z)
return distance
}
}

Result:

// The distance is:  SIMD3<Float>(4.11, 1.32, 4.21)

// The position is: SIMD3<Float>(0.0, 0.0, 0.0)

Get distance between the entity anchor and the camera

You need to perform a Convex Raycast against all the geometry in the RealityKit's scene for a ray between two end points:

import UIKit
import RealityKit

class ViewController: UIViewController {

@IBOutlet var arView: ARView!

override func viewDidLoad() {
super.viewDidLoad()

let entity = ModelEntity(mesh: .generateBox(size: 0.4))
entity.name = "Cube"

let anchor = AnchorEntity(world: [0,0,0])
anchor.addChild(entity)
arView.scene.anchors.append(anchor)

// For every entity that could be hit,
// we must generate a collision shape.
entity.generateCollisionShapes(recursive: true)
}

@IBAction func onTap(_ sender: UITapGestureRecognizer) {

let query: CollisionCastQueryType = .nearest
let mask: CollisionGroup = .default

let camera = arView.session.currentFrame?.camera
let x = (camera?.transform.columns.3.x)!
let y = (camera?.transform.columns.3.y)!
let z = (camera?.transform.columns.3.z)!

let transform: SIMD3<Float> = [x, y, z]

let raycasts: [CollisionCastHit] = arView.scene.raycast(
from: transform,
to: [0, 0, 0],
query: query,
mask: mask,
relativeTo: nil)

guard let raycast: CollisionCastHit = raycasts.first
else { return }

print(raycast.distance) // Distance from the ray origin to the hit
print(raycast.entity.name) // The entity that was hit
print(raycast.position) // The position of the hit
}
}

Also, as @maxxfrazer suggested, you can access camera transforms more easily:

let translate = arView.cameraTransform.translation

let x = translate.x
let y = translate.y
let z = translate.z

let transform: SIMD3<Float> = [x, y, z]

ARKit - getting distance from camera to anchor

The last column of a 4x4 transform matrix is the translation vector (or position relative to a parent coordinate space), so you can get the distance in three dimensions between two transforms by simply subtracting those vectors.

let anchorPosition = anchor.transforms.columns.3
let cameraPosition = camera.transform.columns.3

// here’s a line connecting the two points, which might be useful for other things
let cameraToAnchor = cameraPosition - anchorPosition
// and here’s just the scalar distance
let distance = length(cameraToAnchor)

What you’re doing isn’t working right because you’re subtracting the z-coordinates of each vector. If the two points are different in x, y, and z, just subtracting z doesn’t get you distance.

RealityKit – What's the difference between Anchor and Entity translation?

In RealityKit, both AnchorEntity and ModelEntity are subclasses of their parental Entity class, which means that both of these subclasses have a Transform component. This implies that both objects can be moved, rotated and scaled.

The difference between ModelEntity and AnchorEntity is that an anchor is a special object that is automatically tracked in RealityKit. Model or several models need to be attached to the anchor, to prevent models from drifting. Thus, you can move the anchor itself (together with the models attached to it) and each model individually, if you need to.


Answering your question:

For an anchor with a single child, is there any difference between repositioning the anchor and repositioning the child entity?

In that particular case there's no difference. The only thing you need to think of is THIS.



Related Topics



Leave a reply



Submit