ARKit 2.0具有使用World Map的AR数据持久性。我想在以下版本中实现相同的效果。这是我的方法:在检测垂直平面后放置SCNNode并将其添加到本地数组中。
使用FireBase Realtime DB
存储具有唯一锚ID的ARAnchor。
接下来,我在点击重载按钮时从数据库检索ARAnchor。查找具有唯一ID的锚对应的节点,并将其添加为场景根节点的子节点。但这不能像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 archeive" )
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)
}
任何帮助都会得到真正的帮助。
答案 0 :(得分:0)
这不是一个好主意。 ARKit 1.0和ARKit 1.5中的开发人员无法通过Apple工具访问World Map Data
。 Persistence
和Multiuser AR Experience
选项仅在 iOS 12 的 ARKit 2.0 中可用。
ARKit 2.0包含用于保存和检索精确的世界地图数据的所有必需的类,方法和实例属性。不仅iOS 12中的应用程序都支持它,而且操作系统本身也支持它。
为iOS11开发是否有意义?以下是支持iOS12的设备列表(ARKit降低了对iPhone 6s和更高版本以及iPad 2017和更高版本的兼容性):
有关ARWorldMap类的Apple开发人员文档。
在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
}