从 3d 对象创建 ARRaycastQuery

Create ARRaycastQuery from 3d object

我正在使用 ARKit 和 SceneKit 开发应用程序。

是否可以使用场景中对象的 ARRaycastQuery 创建光线投射查询?

根据上图,我试图从 [3d 对象] 投射光线并在该方向找到一个平面。

这就是我正在尝试的:

    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")
        }
    }

我试图获取 [object] 的位置,并通过操纵 'z' 轴从 2m 远的地方开始射线并向前 2m 的方向。但是,查询总是失败,我做错了什么?有可能吗?

如果你使用 ARKit,你可以实现 3 种不同的光线投射方法:

  • 光线投射(_:)

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.

  • raycastQuery(from:allowing:alignment:)

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.

  • trackedRaycast(_:updateHandler:)

This instance method repeats a raycast query over time to notify you of updated surfaces in the physical environment.

但正如我所见,您需要实现一种方法,该方法从一个 3d 对象创建一条光线,该光线必须击中场景中的另一个 3d 对象。在这种情况下,您需要实现一个可以在 ARView 场景中使用的 RealityKit 实例方法:

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]

在实际代码中可能如下所示:

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)

但请记住!

该方法会忽略缺少 CollisionComponent 的实体。因此,在使用上述方法之前,您需要为未来的命中模型分配碰撞形状。