I am developing an app using ARKit and SceneKit.
Is it possible to create raycast query using ARRaycastQuery from an object in the scene?
As per the picture above, I am trying to cast a ray from [3d object] and find a plane in that direction.
This is what I am trying:
let location = objectNode.simdWorldPosition
let startRayPoint = simd_float3(location.x, location.y, location.z + 2.0)
let endRayPoint = simd_float3(location.x, location.y, location.z - 2.0)
let query = ARRaycastQuery(origin: startRayPoint, direction: endRayPoint, allowing: .estimatedPlane, alignment: .any)
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { (timer) in
if let result = self.sceneView.castRay(for: query).first {
print("castRay result: \(result)")
} else {
print("failed to cast ray")
}
}
I tried to get the location of the [object] and start ray from 2m away and direction to 2m forward by manipulating the 'z' axis. However, the query always fails, what am I doing wrong? Is it even possible?
If you're using ARKit you can implement 3 different ray-casting methods:
This instance method checks once for intersections between a ray (the ray you create from a screen point you're interested in) and real-world surfaces.
This instance method creates a raycast query that originates from a point on the view, aligned with the center of the camera's field of view.
This instance method repeats a raycast query over time to notify you of updated surfaces in the physical environment.
But as I see you need to implement a method that creates a ray from one 3d object that must hit another 3d object in a scene. In that case you need to implement a RealityKit's instance method that can be used inside ARView's scene:
raycast(from:to:query:mask:relativeTo:)
This method performs a
convex ray cast
against all the geometry in the scene for a ray between two end points.
func raycast(from startPosition: SIMD3<Float>,
to endPosition: SIMD3<Float>,
query: CollisionCastQueryType = .all,
mask: CollisionGroup = .all,
relativeTo referenceEntity: Entity? = nil) -> [CollisionCastHit]
In real code it might look like this:
import RealityKit
let raycasts: [CollisionCastHit] = arView.scene.raycast(from: [2, 2, 2],
to: [9, 9, 9],
query: .all,
mask: .all,
relativeTo: nil)
guard let rayCast: CollisionCastHit = raycasts.first
else { return }
print(rayCast.entity.name)
print(rayCast.distance)
But remember!
The method ignores entities that lack a CollisionComponent. So, before using aforementioned method you need to assign collision shape for a future hit-model.