我有一个固定的激光束SCNNode和一个检测球SCNNode连接在一个摄像头前。
如何在没有物理交互的情况下检测穿透?我没有找到任何线索。
EDIT:-如下文maxxFrazer所建议的那样,我实现了物理交互,并且我能够注册碰撞,如果我的激光束是.静态的,并且检测器通过摄像机设置.运动学移动。
如果你需要在没有物理交互的情况下检测穿透,请使用以下方法 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+中使用,我的名字叫 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
}
看起来你想使用SceneKit解决方案,而不是RealityKit。而且还想找到两个实际节点相交的时间,而不是hitTest或raycast?如果是这样,我已经尝试在下面解释如何设置......
首先给SCNNode添加一个physicsBody,以及一个 类别位掩码 + 接触测试位掩码. 这两个基本上是说你的SCNNode主体是什么类别,以及它可以碰撞什么类别。
然后你还需要把你的SCNScene.physicsWorld.contactDelegate设置成一个对象,这个对象符合 SCNPhysicsContactDelegate这是为了让你可以使用物理世界的回调。此处.
还有一个关于堆栈溢出的问题,可能会帮助你实现这个工作。