ARKit – 使用世界光线而不是屏幕点进行光线投射

ibr*_*him 5 augmented-reality swift arkit arcore realitykit

我想要实现类似于ARCore 的光线投射方法的东西,该方法采用世界空间坐标中的任意光线而不是屏幕空间点:

List<HitResult> hitTest (float[] origin3, int originOffset, float[] direction3, int directionOffset)
Run Code Online (Sandbox Code Playgroud)

我发现 ARKit 本身没有这样的方法,但无论如何也许有人有一个想法!

谢谢。

ARG*_*Geo 6

在 Apple RealityKit 和 ARKit 框架中,您可以找到三种主要类型的Raycast方法:ARView RaycastARSession RaycastScene Raycast(或 World Raycast)。所有方法都是用 Swift 编写的:


ARView.raycast(来自:允许:对齐:)

此实例方法执行光线投射,其中光线从相机中心通过视图中的点投射到场景中,并立即返回结果。您可以在 ARKit 中使用这种类型的光线投射。

func raycast(from point: CGPoint, 
        allowing target: ARRaycastQuery.Target, 
              alignment: ARRaycastQuery.TargetAlignment) -> [ARRaycastResult]
Run Code Online (Sandbox Code Playgroud)


ARView.scene.raycast(原点:方向:查询:掩码:relativeTo:)

世界光线投射

此实例方法针对给定原点、方向和长度的光线对场景中的所有几何体执行凸光线投射。

func raycast(origin: SIMD3<Float>, 
          direction: SIMD3<Float>,
              query: CollisionCastQueryType, 
               mask: CollisionGroup, 
         relativeTo: Entity) -> [CollisionCastHit]
Run Code Online (Sandbox Code Playgroud)


ARView.session.trackedRaycast(_:updateHandler:)

此实例方法随着时间的推移重复光线投射查询,以通知您物理环境中的更新表面。您可以在 ARKit 3.5 中使用这种类型的光线投射。

func trackedRaycast(_ query: ARRaycastQuery, 
              updateHandler: @escaping ([ARRaycastResult]) -> Void) -> ARTrackedRaycast?
Run Code Online (Sandbox Code Playgroud)


ARView.trackedRaycast(来自:允许:对齐:updateHandler :)

此 RealityKit 的实例方法还执行跟踪光线投射,但此处光线从相机中心通过视图中的点投射到场景中。

func trackedRaycast(from point: CGPoint, 
               allowing target: ARRaycastQuery.Target, 
                     alignment: ARRaycastQuery.TargetAlignment, 
                 updateHandler: @escaping ([ARRaycastResult]) -> Void) -> ARTrackedRaycast?
Run Code Online (Sandbox Code Playgroud)


代码片段01:

import RealityKit

let startPosition: SIMD3<Float> = [3,-2,0]
let endPosition: SIMD3<Float> = [10,7,-5]
let query: CollisionCastQueryType = .all
let mask: CollisionGroup = .all

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

guard let rayCast: CollisionCastHit = raycasts.first
else { 
    return 
}
Run Code Online (Sandbox Code Playgroud)

代码片段02:

import ARKit

let query = arView.raycastQuery(from: screenCenter,
                            allowing: .estimatedPlane,
                           alignment: .any)

let raycast = session.trackedRaycast(query) { results in

    if let result = results.first {
        object.transform = result.transform
    } 
}

raycast.stop()
Run Code Online (Sandbox Code Playgroud)