我尝试使用 Apple ARGeotracking 加载房屋的 3D 模型。我提供了纬度和经度位置,以便在该特定位置加载对象。但是该对象并未锚定到特定的经纬度位置。此外,对象往往会随着用户的移动而移动。
水平面检测代码
// Create a new AR Scene View.
sceneView = ARSCNView(frame: view.bounds)
sceneView.delegate = self
// Show statistics such as fps and timing information
sceneView.showsStatistics = true
view.addSubview(sceneView)
//configure scene view session to detect horizontal planes
let configuration = ARWorldTrackingConfiguration()
configuration.planeDetection = .horizontal
sceneView.session.run(configuration)
//uncomment to see feature points
sceneView.debugOptions = [ARSCNDebugOptions.showFeaturePoints]
// 响应用户点击 AR 视图。
@objc
func handleTapOnARView(_ sender: UITapGestureRecognizer) {
addGeoAnchor(at: projectLocation2D)
}
添加 ARGeoAnchor 并在参数中提供纬度位置位置
//标记:- 添加土锚
func addGeoAnchor(at location: CLLocationCoordinate2D, altitude: CLLocationDistance? = nil) {
var geoAnchor: ARGeoAnchor!
if let altitude = altitude {
geoAnchor = ARGeoAnchor(coordinate: location, altitude: altitude)
} else {
geoAnchor = ARGeoAnchor(coordinate: location)
}
addGeoAnchor(geoAnchor)
}
func addGeoAnchor(_ geoAnchor: ARGeoAnchor) {
// Don't add a geo anchor if Core Location isn't sure yet where the user is.
guard isGeoTrackingLocalized else {
alertUser(withTitle: "Cannot add geo anchor", message: "Unable to add geo anchor because geo tracking has not yet localized.")
return
}
arView.session.add(anchor: geoAnchor)
}
var isGeoTrackingLocalized: Bool {
if let status = arView.session.currentFrame?.geoTrackingStatus, status.state == .localized {
return true
}
return false
}
func distanceFromDevice(_ coordinate: CLLocationCoordinate2D) -> Double {
if let devicePosition = locationManager.location?.coordinate {
return MKMapPoint(coordinate).distance(to: MKMapPoint(devicePosition))
} else {
return 0
}
}
// MARK: - ARSessionDelegate
func session(_ session: ARSession, didAdd anchors: [ARAnchor]) {
for geoAnchor in anchors.compactMap({ $0 as? ARGeoAnchor }) {
// Effect a spatial-based delay to avoid blocking the main thread.
DispatchQueue.main.asyncAfter(deadline: .now() + (distanceFromDevice(geoAnchor.coordinate) / 10)) {
// Add an AR placemark visualization for the geo anchor.
self.arView.scene.addAnchor(Entity.placemarkEntity(for: geoAnchor))
}
// Add a visualization for the geo anchor in the map view.
let anchorIndicator = AnchorIndicator(center: geoAnchor.coordinate)
// Remember the geo anchor we just added
let anchorInfo = GeoAnchorWithAssociatedData(geoAnchor: geoAnchor, mapOverlay: anchorIndicator)
self.geoAnchors.append(anchorInfo)
}
}
调用了 didAdd 锚方法,在这里我提供了加载模型的 url,因为我使用 EchoAR sdk 将模型加载到我们的应用程序中。模型加载但它没有锚定到特定的地理位置。这里 modelURL 的值来自我使用的 echoAR sdk。它以 .usdz 格式返回模型。
extension Entity {
static func placemarkEntity(for arAnchor: ARAnchor) -> AnchorEntity {
let placemarkAnchor = AnchorEntity(anchor: arAnchor)
if modelURL != nil{
let entity = (try? Entity.load(contentsOf: modelURL!))!
placemarkAnchor.addChild(entity)
}
else{
Utilities.sharedInstance.showError(message: "8C. ===Unable to render AR Model===")
}
return placemarkAnchor
}
}