从3d对象创建ARRaycastQuery

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

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

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

Scene

根据上面的图片,我试图投射来自[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")
        }
    }

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

swift xcode augmented-reality scenekit arkit
1个回答
0
投票

如果您使用的是ARKit,则可以实现3种不同的射线投射方法

  • raycast(_:)

此实例方法检查一次射线(您从感兴趣的屏幕点创建的射线)与真实表面之间的交集。

  • raycastQuery(from:allowing:alignment:)

此实例方法创建一个从视图上与相机视场中心对齐的点开始的raycast查询。

  • trackedRaycast(_:updateHandler:)

此实例方法会随着时间的推移重复射线广播查询,以通知您物理环境中的更新曲面。

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

raycast(from:to:query:mask:relativeTo:)

此方法针对场景中的所有几何图形对两个端点之间的光线执行convex ray cast

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的实体。

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