美文网首页基础知识移动客户端
【译】可视化并与重构的场景进行交互

【译】可视化并与重构的场景进行交互

作者: loongod | 来源:发表于2020-11-05 10:15 被阅读0次

    使用多边形网格估算物理环境的形状。

    官方Demo下载


    一、总览

    在运行iPad OS 13.4或更高版本的第四代iPad Pro上,ARKit使用LiDAR扫描仪创建物理环境的多边形模型。LiDAR扫描仪可从用户面前的广阔区域快速检索深度信息,因此ARKit无需用户移动即可估算真实世界的形状。ARKit将深度信息转换为一系列顶点,这些顶点相互连接以形成网格。为了划分信息,ARKit制作了多个锚,每个锚分配了网格的唯一部分。网格锚共同代表了用户周围的真实场景。

    使用这些网格,您可以:

    • 更精确地定位现实表面上的点。
    • 对ARKit可以识别的真实对象进行分类。
    • 使用位于其前面的真实对象来遮挡应用程序的虚拟内容。
    • 让虚拟内容与物理环境进行实际交互,例如,通过将虚拟球从现实世界的墙壁上弹起,并使球遵循物理定律。

    该示例应用程序展示了使用RealityKit的AR体验。下图说明了RealityKit如何利用ARKit的真实信息,并在运行该应用并将设备指向真实椅子时创建调试可视化效果。

    meshing3-annotated.png

    二、可视化物理环境的形状

    为了启用场景网格物体,该示例将 world-configurationsceneReconstruction属性设置为网格物体选项之一。

    arView.automaticallyConfigureSession = false
    let configuration = ARWorldTrackingConfiguration()
    configuration.sceneReconstruction = .meshWithClassification
    

    该示例使用 RealityKit 的 ARView渲染其图形。要在运行时可视化网格,请ARView提供.showSceneUnderstanding 调试选项。

    arView.debugOptions.insert(.showSceneUnderstanding)
    

    注意
    该示例启用了网格可视化,仅用于演示网格特征。同样,通常仅出于调试目的而启用网格可视化

    为了开始AR体验,该示例在主视图控制器的 viewDidLoad 回调中配置并在应用程序首次启动时运行会话。

    arView.session.run(configuration)
    

    三、添加平面检测

    当应用通过场景重建启用平面检测时,ARKit在制作网格时会考虑该信息。如果LiDAR扫描仪可能在真实表面上产生稍微不均匀的网格,则ARKit会在检测到该表面上的平面的地方平滑网格。

    为了演示平面检测对网格的影响,此应用程序显示一个切换按钮。在按钮处理程序中,该示例调整了平面检测配置并重新启动了会话以实现更改。

    @IBAction func togglePlaneDetectionButtonPressed(_ button: UIButton) {
        guard let configuration = arView.session.configuration as? ARWorldTrackingConfiguration else {
            return
        }
        if configuration.planeDetection == [] {
            configuration.planeDetection = [.horizontal, .vertical]
            button.setTitle("Stop Plane Detection", for: [])
        } else {
            configuration.planeDetection = []
            button.setTitle("Start Plane Detection", for: [])
        }
        arView.session.run(configuration)
    }
    

    四、在对象表面上找到一个点

    使用网格检索表面位置的应用程序可以达到前所未有的准确性。通过考虑网格,射线投射可以与非平面表面或具有很少或没有特征的表面(如白墙)相交。

    为了演示准确的光线投射结果,该应用程序在用户点击屏幕时投射光线。该示例根据需要指定了 .estimatedPlane 允许目标和对齐选项 .any,以检索网格现实对象上的点。

    let tapLocation = sender.location(in: arView)
    if let result = arView.raycast(from: tapLocation, allowing: .estimatedPlane, alignment: .any).first {
        // ...
    
    armchair-annotated.png

    当用户的射线投射返回结果时,此应用通过在交点处放置一个小球体来提供视觉反馈。

    let resultAnchor = AnchorEntity(world: result.worldTransform)
    resultAnchor.addChild(sphere(radius: 0.01, color: .lightGray))
    arView.scene.addAnchor(resultAnchor, removeAfter: 3)
    
    insersection-sphere-annotated.png

    五、分类真实世界的对象

    ARKit具有分类功能,可以分析其网格化的世界模型以识别特定的实际对象。在网格中,ARKit可以对地板,桌子,座椅,窗户和天花板进行分类。请参阅完整列表ARMeshClassification

    如果用户点击屏幕,并且射线投射与现实的网格物体相交,则此应用程序将显示网格类别的文本。

    classified-sized.png

    ARViewautomaticallyConfigureSession属性为True时,默认情况下RealityKit禁用分类,因为遮挡和物理过程不需要它。要启用网格分类,样本将sceneReconstruction属性设置为.meshWithClassification 来覆盖默认值。

    arView.automaticallyConfigureSession = false
    let configuration = ARWorldTrackingConfiguration()
    configuration.sceneReconstruction = .meshWithClassification
    

    该应用程序尝试从网格中检索相交点的分类。

    nearbyFaceWithClassification(to: result.worldTransform.position) {
     (centerOfFace, classification) in
    
    

    网格中的每三个顶点形成一个三角形,称为面。ARKit为每个面分配一个分类,因此样本在网格中搜索相交点附近的面。如果脸部有分类,则此应用程序将其显示在屏幕上。由于此例程涉及大量处理,示例将异步执行工作,所以渲染器不会停止。

    DispatchQueue.global().async {
        for anchor in meshAnchors {
            for index in 0..<anchor.geometry.faces.count {
                // Get the center of the face so that we can compare it to the given location.
                let geometricCenterOfFace = anchor.geometry.centerOf(faceWithIndex: index)
                
                // Convert the face's center to world coordinates.
                var centerLocalTransform = matrix_identity_float4x4
                centerLocalTransform.columns.3 = SIMD4<Float>(geometricCenterOfFace.0, geometricCenterOfFace.1, geometricCenterOfFace.2, 1)
                let centerWorldPosition = (anchor.transform * centerLocalTransform).position
                 
                // We're interested in a classification that is sufficiently close to the given location––within 5 cm.
                let distanceToFace = distance(centerWorldPosition, location)
                if distanceToFace <= 0.05 {
                    // Get the semantic classification of the face and finish the search.
                    let classification: ARMeshClassification = anchor.geometry.classificationOf(faceWithIndex: index)
                    completionBlock(centerWorldPosition, classification)
                    return
                }
            }
        }
    

    有了分类,示例将创建3D文本以显示它。

    let textEntity = self.model(for: classification)
    

    为了防止网格物体部分遮挡文本,示例会稍微偏移文本以提高可读性。该示例计算光线负向的偏移量,该偏移量可有效地将文本稍微移向远离曲面的相机。

    let rayDirection = normalize(result.worldTransform.position - self.arView.cameraTransform.translation)
    let textPositionInWorldCoordinates = result.worldTransform.position - (rayDirection * 0.1)
    

    为了使文本始终在屏幕上显示相同的大小,该示例将根据文本与相机的距离应用比例尺。

    let raycastDistance = distance(result.worldTransform.position, self.arView.cameraTransform.translation)
    textEntity.scale = .one * raycastDistance
    

    为了显示文本,示例将其放在调整后的相交点的锚定实体中,该交点的方向是面向镜头。

    var resultWithCameraOrientation = self.arView.cameraTransform
    resultWithCameraOrientation.translation = textPositionInWorldCoordinates
    let textAnchor = AnchorEntity(world: resultWithCameraOrientation.matrix)
    textAnchor.addChild(textEntity)
    self.arView.scene.addAnchor(textAnchor, removeAfter: 3)
    

    为了从检索的分类中可视化表面顶点的位置,该样本在顶点的真实位置上创建了一个小球体。

    if let centerOfFace = centerOfFace {
        let faceAnchor = AnchorEntity(world: centerOfFace)
        faceAnchor.addChild(self.sphere(radius: 0.01, color: classification.color))
        self.arView.scene.addAnchor(faceAnchor, removeAfter: 3)
    }
    
    classified-text-annotated.png

    六、用网格遮挡虚拟内容

    遮挡是一种功能,从摄像机的角度来看,现实世界的某些部分覆盖了应用程序的虚拟内容。为了实现这种幻觉,RealityKit 会检查用户查看的虚拟内容之前是否存在任何网格,并省略绘制那些网格遮盖的虚拟内容的任何部分的操作。该示例通过将occlusion选项添加到环境的sceneUnderstanding属性中来启用遮挡。

    arView.environment.sceneUnderstanding.options.insert(.occlusion)
    

    在运行时,此应用程序忽略了虚拟文本在网状现实世界任何部分后面的绘制部分。

    table-floor-annotated.png

    七、使用物理与现实世界的物体互动

    使用场景网格,虚拟内容可以与物理环境进行实际交互,因为网格为RealityKit的物理引擎提供了一个精确的世界模型。该示例通过将physics选项添加到环境的 sceneUnderstanding 属性中来启用物理学。

    为了检测虚拟内容何时与网状现实对象接触,该示例使用扩展名中的碰撞形状定义了文本的大小。在Scene的扩展 addAnchor(_:,removeAfter:) 方法中。

    Timer.scheduledTimer(withTimeInterval: seconds, repeats: false) { (timer) in
        model.physicsBody?.mode = .dynamic
    }
    

    当文本掉落时,它与网状现实世界对象(例如降落在地板上)碰撞时会做出反应。

    windows-annotated.png

    相关文章

      网友评论

        本文标题:【译】可视化并与重构的场景进行交互

        本文链接:https://www.haomeiwen.com/subject/ehkovktx.html