【问题标题】:RealityKit – Image recognition and working with many scenesRealityKit - 图像识别和处理许多场景
【发布时间】:2021-04-17 00:52:34
【问题描述】:

我使用 RealityKit 模板文件创建了一个应用程序。 RealityComposer 内部有多个场景,所有场景都使用图像识别激活一些动画。

在 Xcode 中,我必须将所有场景作为锚点加载,并将这些锚点附加到 arView.scene.anchors 数组。这个问题很明显,因为我一个接一个地呈现物理 2D 图像,我得到多个锚点堆叠在一起,这是不可取的。在加载新锚之前我知道arView.scene.anchors.removeAll(),但我的问题是:

我如何检查某个图像何时出现从而删除现有锚并加载正确的锚?我试图在 ARKit 中寻找类似 @​​987654323@ 的东西,但我在 RealityKit 中看不到类似的东西。

非常感谢

【问题讨论】:

    标签: swift augmented-reality arkit realitykit reality-composer


    【解决方案1】:

    前言

    RealityKit 的 AnchorEntity(.image) 来自 RC,与 ARKit 的 ARImageTrackingConfig 匹配。当 iOS 设备识别参考图像时,它会创建图像锚点(符合ARTrackable 协议),用于绑定相应的 3D 模型。而且,正如您所理解的,您一次只能显示一张参考图像(在您的特定情况下,当您同时提供两张或更多图像时,AR 应用程序无法正常运行)。


    代码 sn-p 显示 if condition 逻辑的样子:

    import SwiftUI
    import RealityKit
    
    struct ContentView : View {
        var body: some View {            
            return ARViewContainer().edgesIgnoringSafeArea(.all)
        }
    }
    
    struct ARViewContainer: UIViewRepresentable {
    
        func makeUIView(context: Context) -> ARView {    
            let arView = ARView(frame: .zero)
    
            let id02Scene = try! Experience.loadID2()            
            print(id02Scene)     // prints scene hierarchy
            
            let anchor = id02Scene.children[0]
            print(anchor.components[AnchoringComponent] as Any)
            
            if anchor.components[AnchoringComponent] == AnchoringComponent(
                          .image(group: "Experience.reality", 
                                  name: "assets/MainID_4b51de84.jpeg")) {
                
                arView.scene.anchors.removeAll()
                print("LOAD SCENE")
                arView.scene.anchors.append(id02Scene)
            }
            return arView
        }
     
        func updateUIView(_ uiView: ARView, context: Context) { }
    }
    

    ID2 在控制台打印场景层次结构:

    附言

    你应该实现 SwiftUI Coordinator 类(阅读它here),并在 Coordinator 内部使用 ARSessionDelegate 的 session(_:didUpdate:) 实例方法以 60 fps 更新锚属性。

    您也可以使用以下逻辑 - 如果场景 1 的锚点处于活动状态或场景 3 的锚点处于活动状态,则只需从集合中删除所有锚点并加载场景 2。

    var arView = ARView(frame: .zero)
    
    let id01Scene = try! Experience.loadID1()
    let id02Scene = try! Experience.loadID2()
    let id03Scene = try! Experience.loadID3()
    
    func makeUIView(context: Context) -> ARView {    
        arView.session.delegate = context.coordinator
    
        arView.scene.anchors.append(id01Scene)
        arView.scene.anchors.append(id02Scene)
        arView.scene.anchors.append(id03Scene)
        return arView
    }
    

    ...

    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        if arView.scene.anchors[0].isActive || arView.scene.anchors[2].isActive {
            arView.scene.anchors.removeAll()
            arView.scene.anchors.append(id02Scene)
            print("Load Scene Two")
        }
    }
    

    【讨论】:

    • 感谢您,但是我收到此错误“在范围内找不到'anchorInRealityComposerScene'”。我想我应该在那里放置我自己的自定义名称,否则它会超出范围。
    • anchorInRealityComposerScene 是场景层次结构中锚点的抽象名称...
    • 我看到您指的是 Composer 场景中的锚点,但我能看到的对锚点的唯一访问只是使用“arView.scene.anchors.components[AnchoringComponent]”,这会引发错误“AnchorCollection没有成员“组件””
    • 如果我要使用加载体验场景中的引用,我实际上可以一次将所有场景加载到一个变量中,以便我可以检查那个 variable.components 吗?我在网上找到的只是逐个场景加载,但我需要一个同时引用所有场景的变量,不是吗?
    • 快到了! :) 在相机视图中的参考图像消失后,我只是让模型锚点持续存在。所以我同时在屏幕上看到了多个实体。我想我需要在这里使用 updateUIView() 方法?
    猜你喜欢
    • 2013-04-02
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 1970-01-01
    • 2012-12-06
    相关资源
    最近更新 更多