在ARKit中如何在没有物理交互的情况下检测穿透?

问题描述 投票:1回答:1

我有一个固定的激光束SCNNode和一个检测球SCNNode连接在一个摄像头前。

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

EDIT:-如下文maxxFrazer所建议的那样,我实现了物理交互,并且我能够注册碰撞,如果我的激光束是.静态的,并且检测器通过摄像机设置.运动学移动。

swift xcode arkit scnnode sceneview
1个回答
1
投票

如果你需要在没有物理交互的情况下检测穿透,请使用以下方法 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 
}

1
投票

看起来你想使用SceneKit解决方案,而不是RealityKit。而且还想找到两个实际节点相交的时间,而不是hitTest或raycast?如果是这样,我已经尝试在下面解释如何设置......

首先给SCNNode添加一个physicsBody,以及一个 类别位掩码 + 接触测试位掩码. 这两个基本上是说你的SCNNode主体是什么类别,以及它可以碰撞什么类别。

然后你还需要把你的SCNScene.physicsWorld.contactDelegate设置成一个对象,这个对象符合 SCNPhysicsContactDelegate这是为了让你可以使用物理世界的回调。此处.

还有一个关于堆栈溢出的问题,可能会帮助你实现这个工作。

检测SceneKit中的碰撞问题

© www.soinside.com 2019 - 2024. All rights reserved.