在Xcode中我们可以通过在Assets下创建”AR Resource Group"来添加需要检测与跟踪的图片(ARReferenceImage), 通过对每张图片的属性设定(如Name, Size, 和Units)以此来达到更好的显示效果。
但截至目前2022年3月10日, Swift Playgrounds Version 4.0.2还没有功能菜单创建AR Resource Group,也没有对图片属性添加的功能窗口。所以为了解决此问题,我们必须通过手动添加参考图像库,参考图片,以及参考图片属性来实现相同的功能,以下为实现过程。
1. 添加照片到资源文件
点击左侧“添加”- 选择“照片”,注意这里一定要添加格式为PNG或JPEG的图片,手机或ipad拍摄的照片格式为HEIF, 可以通过截屏来获取PNG格式。添加后,图片会在“资源”下显示,长按图片可以“重命名”为英文或拼音。
2. 添加3D模型到“资源”文件
点击左侧“添加”- 选择“插入自”,选择你想要展示的格式为usdz的3D模型。添加完成后,模型文件会在左侧“资源”文件下显示。这里可以更改图片名称与相对应模型名称一致。
3. 创建参考图片库,生成参考图片,设置参考图片属性,添加参考图片到库,
3.1 我们需要手动创建参考图片库.
var trackedImageLibs = Set()
3.2 将图片转变为UIImage, 然后转变为CGImage,最后转变为ARReferenceImage, 并设置属性:朝向,实际宽度.
let teapotUIImage = UIImage(named: "teapot")
let carUIImage = UIImage(named: "toy_car")
let drummerUIImage = UIImage(named: "toy_drummer")
let teapotRefImg = ARReferenceImage(teapotUIImage!.cgImage!, orientation: .up, physicalWidth: 0.075)
let carRefImg = ARReferenceImage(carUIImage!.cgImage!, orientation: .up, physicalWidth: 0.075)
let drummerRefImg = ARReferenceImage(drummerUIImage!.cgImage!, orientation: .up, physicalWidth: 0.075)
3.3 给每一个ARReferenceImage的name属性一个值,这个值类型为Optional String. 注意这里的name和资源库里图片的名字是两个东西,如果你在Xcode中添加了参考图片,这里的name就是参考图片属性窗口里的name。如果你手动创建参考图片,这里的name默认值为nil。
teapotRefImg.name = "teapot"
carRefImg.name = "toy_car"
drummerRefImg.name = "toy_drummer"
3.4 将所有参考图片添加进参考图片库
trackedImageLibs.insert(teapotRefImg)
trackedImageLibs.insert(carRefImg)
trackedImageLibs.insert(drummerRefImg)
4. 将我们创建的参考图片库分配给ARImageTrackingConfiguration里的trackingImages(跟踪图片库),因为ARKit只会把trackingImages库里的图片拿去与用户环境中的图片做检测和跟踪。
config.trackingImages = trackedImageLibs
5. 当ARKit检测到相关图片并生成ARImageAnchor时,可以利用ARImageAnchor的referenceImage属性里的name属性,用来加载与之对应的模型。
5.1 如果检测到特征点相匹配的图片,生成ARImageAnchor
guard let imageAnchor = anchors[0] as? ARImageAnchor else {return}
5.2 将ARImageAnchor里的参考图片里的名称分配给一个新的类型为String的常量
let referImageName: String = imageAnchor.referenceImage.name ?? "example"
5.3 根据获得的参考图片名称,加载与之对应的模型
ModelEntity.loadModelAsync(named: referImageName)
优点补充:在swift playgrounds上编写AR应用可以及时预览所呈现效果,避免了在Xcode中需要连接真机安装部署才能测试,其次还避免了免费用户在Xcode每周开发安装App数量限制的问题(未来swift playgrounds会不会有限制,不知道,希望永远不会)
缺点补充:在Xcode中,上传的参考图像会被检测是否具有高对比,多特征等因素,从而指导开发者筛选调整出更容易检测和跟踪的参考图像,优化用户体验。而在swift playgrounds中,开发者目前只能通过自身经验去挑选一些对比度高,特征信息丰富的图片。
以下为完整代码:
import SwiftUI
import ARKit
import RealityKit
import Combine
struct ContentView: View {
var body: some View {
ZStack{
ARViewContainer()
}
}
}
struct ARViewContainer: UIViewRepresentable {
func makeUIView(context: Context) -> ARView {
let arView = ARView(frame: .zero)
let config = ARImageTrackingConfiguration()
var trackedImageLibs = Set()
let teapotUIImage = UIImage(named: "teapot")
let carUIImage = UIImage(named: "toy_car")
let drummerUIImage = UIImage(named: "toy_drummer")
let teapotRefImg = ARReferenceImage(teapotUIImage!.cgImage!, orientation: .up, physicalWidth: 0.075)
let carRefImg = ARReferenceImage(carUIImage!.cgImage!, orientation: .up, physicalWidth: 0.075)
let drummerRefImg = ARReferenceImage(drummerUIImage!.cgImage!, orientation: .up, physicalWidth: 0.075)
teapotRefImg.name = "teapot"
carRefImg.name = "toy_car"
drummerRefImg.name = "toy_drummer"
trackedImageLibs.insert(teapotRefImg)
trackedImageLibs.insert(carRefImg)
trackedImageLibs.insert(drummerRefImg)
config.trackingImages = trackedImageLibs
config.maximumNumberOfTrackedImages = 4
arView.session.run(config, options: [])
arView.session.delegate = arView
return arView
}
func updateUIView(_ uiView: UIViewType, context: Context) {
}
}
extension ARView: ARSessionDelegate {
public func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
guard let imageAnchor = anchors[0] as? ARImageAnchor else {return}
let imageAnchorEntity = AnchorEntity(anchor: imageAnchor)
let referImageName = imageAnchor.referenceImage.name ?? "example"
var cancellable: AnyCancellable? = nil
cancellable = ModelEntity.loadModelAsync(named: referImageName).sink(receiveCompletion: { status in
print("Completion: \(status)")
cancellable?.cancel()
}, receiveValue: { entity in
imageAnchorEntity.addChild(entity)
})
self.scene.addAnchor(imageAnchorEntity)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)