ios - 在 iOS 中的 ARKit 1.0 中持久化 AR 数据

标签 ios swift persistence augmented-reality arkit

ARKit 2.0 具有使用世界地图的 AR 数据持久性。我想为以下版本实现相同的目标。这是我的方法:在检测到垂直平面并添加到本地数组后放置 SCNNode。

使用 FireBase Realtime DB 存储具有唯一 anchor ID 的 ARAnchor。 接下来,我在点击重新加载按钮时从数据库中检索 ARAnchor。查找与具有唯一 ID 的 anchor 对应的节点并将其添加为场景根节点的子节点。但这并不像 ARKit 2.0 那样按预期工作。节点没有放置在最后的确切位置。下面是我的代码:

guard let node = self.selectedNode else { return }
guard let data = try? NSKeyedArchiver.archivedData(withRootObject: node.anchor!, requiringSecureCoding: false) else { print("Could not archive" )
   return 
}

let string = data.base64EncodedString()
self.saveData(dataString: string, forKey: node.name!)

func saveData(dataString : String, forKey : String)  {
    db.collection("roomdecorateDB").document(forKey).setData([
        "anchor": dataString]) { err in
        if let err = err {
            print("Error writing document: \(err)")
        } else {
            print("Document successfully written!")
        }
    }
}

func reloadData() { 
    guard let cloudAnchor = try? NSKeyedUnarchiver.unarchivedObject(ofClass: ARAnchor.self, from: data) else { return print("Could not decode") }
    print("world map \(cloudAnchor!)")
    // Run the session with the received world map.
    let configuration = self.standardConfiguration
    self.sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
    self.sceneView.session.add(anchor: cloudAnchor!)
    // document id is the name of node, we can find node from node array and place to scene view
    guard  let node = self.nodeArray.first(where: {$0.name == document.documentID})else {continue}
    node.position = SCNVector3((cloudAnchor?.transform.columns.3.x)!, (cloudAnchor?.transform.columns.3.y)!, (cloudAnchor?.transform.columns.3.z)!)
    self.sceneView.scene.rootNode.addChildNode(node)
}

非常感谢任何帮助。

最佳答案

这不是一个好主意。 ARKit 1.0 和 ARKit 1.5 中的开发人员无法通过 Apple 工具访问世界地图数据PersistenceMultiuser AR Experience 选项仅在适用于 iOS 12ARKit 2.0 中可用。

ARKit 2.0 contains all necessary classes, methods and instance properties for saving and retrieving precise World Map Data. It's supported not only by apps in iOS 12 but the Operating System itself.

Does it make sense to develop for iOS11? Here's a list of devices supporting iOS12 (ARKit cuts compatibility to iPhones 6s and higher and iPad 2017 and higher):

enter image description here

Apple Developer Documentation about ARWorldMap class.

在 iOS12 中将 ARWorldMap 保存到文件 URL 就这么简单:

func writeWorldMap(_ worldMap: ARWorldMap, to url: URL) throws {
    let data = try NSKeyedArchiver.archivedData(withRootObject: worldMap, requiringSecureCoding: true)
    try data.write(to: url)
}

从文件 URL 加载 ARWorldMap 就这么简单:

func loadWorldMap(from url: URL) throws -> ARWorldMap {
    let mapData = try Data(contentsOf: url)
    guard let worldMap = try NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: mapData)
        else { throw ARError(.invalidWorldMap) }
    return worldMap
}

关于ios - 在 iOS 中的 ARKit 1.0 中持久化 AR 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52779077/

相关文章:

ios - 使用 TwitterKit 访问 twitter 流 api

swift - 在 UIDatePicker 中删除日期的可选字符串

database - 如何持久化仅包含集合和 ID 的实体?

ios - XCode - 图像上触摸事件的精确相对坐标 - iOS

ios - Swift 3 viewDidLoad() - fatal error : unexpectedly found nil while unwrapping an Optional value

ios - swift - 声明计算属性以调用具有多个返回值的函数

ios - 如何以编程方式将 UIBarButtonItem 添加到拖到 View 上的 UINavigationBar

grails - Grails域对象看起来像是永久保存的,但实际上不是

java - Android Studio加载内部存储数据错误

ios - 使用 Appcelerator 和 IOS 部署时的工作流程