RealityKit – 图像识别和处理许多场景
RealityKit – Image recognition and working with many scenes
我使用 RealityKit 模板文件创建了一个应用程序。 RealityComposer内部有多个场景,所有场景都使用图像识别激活一些动画。
在 Xcode 中,我必须将所有场景加载为锚点并将这些锚点附加到 arView.scene.anchors
数组。这个问题很明显,当我一个接一个地呈现物理 2D 图像时,我得到多个锚点堆叠在一起,这是不可取的。在加载新锚点之前我知道 arView.scene.anchors.removeAll()
但我的问题是:
如何检查某个图像何时出现,从而删除现有的锚点并加载正确的锚点?我试图在 ARKit 中寻找类似 didUpdate
的东西,但我在 RealityKit 中看不到任何类似的东西。
非常感谢
前言
RealityKit 的 AnchorEntity(.image)
来自 RC,匹配 ARKit 的 ARImageTrackingConfig。当 iOS 设备识别出参考图像时,它会创建 Image Anchor(符合 ARTrackable
协议)以绑定相应的 3D 模型。而且,如您所知,您必须一次只显示一张参考图像(在您的特定情况下,当您同时提供两张或更多图像时,AR 应用程序无法正常运行)。
显示 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
控制台中打印的场景层次结构:
P.S.
您应该实现 SwiftUI Coordinator
class(了解它 ), and inside Coordinator use ARSessionDelegate's 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")
}
}
我使用 RealityKit 模板文件创建了一个应用程序。 RealityComposer内部有多个场景,所有场景都使用图像识别激活一些动画。
在 Xcode 中,我必须将所有场景加载为锚点并将这些锚点附加到 arView.scene.anchors
数组。这个问题很明显,当我一个接一个地呈现物理 2D 图像时,我得到多个锚点堆叠在一起,这是不可取的。在加载新锚点之前我知道 arView.scene.anchors.removeAll()
但我的问题是:
如何检查某个图像何时出现,从而删除现有的锚点并加载正确的锚点?我试图在 ARKit 中寻找类似 didUpdate
的东西,但我在 RealityKit 中看不到任何类似的东西。
非常感谢
前言
RealityKit 的 AnchorEntity(.image)
来自 RC,匹配 ARKit 的 ARImageTrackingConfig。当 iOS 设备识别出参考图像时,它会创建 Image Anchor(符合 ARTrackable
协议)以绑定相应的 3D 模型。而且,如您所知,您必须一次只显示一张参考图像(在您的特定情况下,当您同时提供两张或更多图像时,AR 应用程序无法正常运行)。
显示 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
控制台中打印的场景层次结构:
P.S.
您应该实现 SwiftUI Coordinator
class(了解它
也可以使用以下逻辑——如果场景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")
}
}