首页 > 解决方案 > 如何在 ARKit 中检测没有物理交互的穿透?

问题描述

我有一个固定的激光束 SCNNode 和一个连接在相机前面的检测球 SCNNode。

如何在没有物理交互的情况下检测渗透?我没有找到任何线索..

编辑: - 正如maxxFrazer在下面建议的那样,我实现了物理交互,如果我的激光束是.static并且检测器由相机组.kinematic移动,我能够记录碰撞。

标签: swiftaugmented-realityscenekitarkit

解决方案


如果您需要在没有物理交互的情况下检测渗透,请使用trackedRaycast在 iOS 13+ 中工作的实例方法:

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

trackedRaycast(_:updateHandler:)随着时间的推移重复射线投射查询,以通知您物理环境中更新的表面。

这是它的样子:

import ARKit

let query = arView.raycastQuery(from: screenCenter,
                            allowing: .estimatedPlane, // also specifies nonplanar geo
                           alignment: .any)

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

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

raycast.stop()

请记住,trackedRaycast实例方法反复撞击表面,因此如果不再需要它,则必须停止它。


但是,如果您需要凸光线投射,请使用 RealityKit 的实例方法,该方法也适用于 iOS 13+ 并且 i 被称为raycast(origin:direction:query:mask:relativeTo:).

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

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

import RealityKit

let startPosition: SIMD3<Float> = [7,7,7]
let endPosition: SIMD3<Float> = [-10,18,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 
}

推荐阅读