Machineboy空
Realitykit 입문 - Persistence 본문
Saving world map
userDefault를 사용해서 AnchorEntity가 아닌 ARKit의 ARAnchor를 저장하고 껐다 켰을 때 불러올 것이다.
// 오류가 있는지.. 작동을 안함 어쩌다 한번 작동된다 나중에 다시 오리!
import Foundation
import ARKit
import RealityKit
class Coordinator: NSObject, ARSessionDelegate {
let vm: ViewModel
var arView: ARView?
init(vm: ViewModel) {
self.vm = vm
}
@objc func onTap(_ recognizer: UITapGestureRecognizer) {
guard let arView = arView else {
return
}
let location = recognizer.location(in: arView)
let results = arView.raycast(from: location, allowing: .estimatedPlane, alignment: .horizontal)
if let result = results.first {
let arAnchor = ARAnchor(name: "boxAnchor", transform: result.worldTransform)
let anchor = AnchorEntity(anchor: arAnchor)
let box = ModelEntity(mesh: MeshResource.generateBox(size: 0.3), materials: [SimpleMaterial(color: .green, isMetallic: true)])
arView.session.add(anchor: arAnchor)
anchor.addChild(box)
arView.scene.addAnchor(anchor)
}
}
func loadWorldMap() {
guard let arView = arView else {
return
}
let userDefaults = UserDefaults.standard
if let data = userDefaults.data(forKey: "worldMap") {
guard let worldMap = try? NSKeyedUnarchiver.unarchivedObject(ofClass: ARWorldMap.self, from: data) else { return }
for anchor in worldMap.anchors {
let anchorEntity = AnchorEntity(anchor: anchor)
let box = ModelEntity(mesh: MeshResource.generateBox(size: 0.3), materials: [SimpleMaterial(color: .yellow, isMetallic: false)])
anchorEntity.addChild(box)
arView.scene.addAnchor(anchorEntity)
}
let configuration = ARWorldTrackingConfiguration()
configuration.initialWorldMap = worldMap
configuration.planeDetection = .horizontal
arView.session.run(configuration)
}
}
func saveWorldMap() {
guard let arView = arView else {
return
}
arView.session.getCurrentWorldMap { [weak self] worldMap, error in
if let error = error {
print(error)
return
}
if let worldMap = worldMap {
guard let data = try? NSKeyedArchiver.archivedData(withRootObject: worldMap, requiringSecureCoding: true) else {
return
}
let userDefaults = UserDefaults.standard
userDefaults.set(data, forKey: "worldMap")
userDefaults.synchronize() // leave out synchronize, it will be saved on its own
self?.vm.isSaved = true
}
}
}
func clearWorldMap() {
guard let arView = arView else {
return
}
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = .horizontal
arView.session.run(configuration, options: [.removeExistingAnchors, .resetTracking])
let userDefaults = UserDefaults.standard
userDefaults.removeObject(forKey: "worldMap")
userDefaults.synchronize()
}
func session(_ session: ARSession, didUpdate frame: ARFrame) {
switch frame.worldMappingStatus {
case .notAvailable: vm.worldMapStatus = .notAvailable
case .limited: vm.worldMapStatus = .limited
case .extending: vm.worldMapStatus = .exptending
case .mapped: vm.worldMapStatus = .mapped
@unknown default: fatalError()
}
}
}
'언어 > iOS' 카테고리의 다른 글
iBeacon이란? beacon과 iOS 디바이스 간 거리 감지! (3) | 2024.10.29 |
---|---|
RealityKit 입문 - 한국에선 불가한 ARGeoAnchor (2) | 2024.10.15 |
RealityKit 입문 - 측정앱 만들기 (0) | 2024.10.15 |
RealityKit 입문 - Physics (1) | 2024.10.14 |
RealityKit 입문 - ARCouchingView 더하기 (0) | 2024.10.14 |