如何使用 ARkit 将 3D 对象放置在 GPS 坐标上

问题描述 投票:0回答:2

与 Project Dent 合作,尝试将 3D 对象置于绝对 GPS 坐标处。

自述文件展示了如何将 2D 信息注释对象放入 AR 空间,但我无法让它将 3D 对象放置在 GPS 坐标

Project Dent 不使用标准 SceneView,这使得很难根据大量教程来尝试执行此操作。它使用基于 ARCL 的 SceneLocationView

这是 2D 注释的示例代码

let coordinate = CLLocationCoordinate2D(latitude: 51.504571, longitude: -0.019717)
let location = CLLocation(coordinate: coordinate, altitude: 300)
let view = UIView() // or a custom UIView subclass

let annotationNode = LocationAnnotationNode(location: location, view: view)

sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: annotationNode)

这是我一直在尝试让它与 3D 对象一起工作的方法

let coordinate = CLLocationCoordinate2D(latitude: 51.504571, longitude: -0.019717)
let location = CLLocation(coordinate: coordinate, altitude: 300)
let box = SCNBox(width: 0.1, height: 0.1, length: 0.1, chamferRadius: 0)

let objectNode = LocationNode(location: location, SCNbox: box)

sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: objectNode)

理想情况下,我希望这段代码能够简单地将 3d 框放置在 AR 空间中的这些 GPS 坐标处。

可悲的是,我目前甚至无法构建它。

作为对此的更新,我已完成以下操作。在 Nodes 中新建一个类,基于 LocationNode,名为 ThreeDNode -

open class ThreeDNode: LocationNode {

   // Class for placing 3d objects in AR space
   public let threeDObjectNode: LocationNode

   public init(location: CLLocation?, scene: SCNScene) {

       let boxGeometry = SCNBox(width: 1, height: 1, length: 1, chamferRadius: 0)
       //let boxNode = SCNNode(geometry: boxGeometry)

       threeDObjectNode = LocationNode(location: location)
       threeDObjectNode.geometry = boxGeometry
       threeDObjectNode.removeFlicker()

       super.init(location: location)

       addChildNode(threeDObjectNode)
   }

   required public init?(coder aDecoder: NSCoder) {
       fatalError("init(coder:) has not been implemented")
   }

然后在 POIViewController 中,尝试使用以下代码将 3D 对象放置在 AR 空间中 -

//example using 3d box object
        let coordinate2 = CLLocationCoordinate2D(latitude: 52.010339, longitude: -8.351157)
        let location2 = CLLocation(coordinate: coordinate2, altitude: 300)

        let asset = SCNScene(named: "art.scnassets/ship.scn")!

        let object = ThreeDNode(location: location2, scene: asset)

        //add to scene with confirmed location
        sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: object)

没有喜悦:(任何帮助,非常感谢。

swift arkit
2个回答
1
投票

您需要创建一个位置节点,并将盒子添加为其几何图形或子节点:

let boxNode = SCNNode(geometry: box)

let locationNode = LocationNode(location: location)
locationNode.addChildNode(boxNode)

sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: locationNode)

我没有在 Xcode 中运行此代码,因此您可能需要调整。


0
投票

我这次谈话有点晚了,但我正在做类似的事情。放置对象是更直接的部分。您需要创建一个场景对象并添加到场景视图,然后将所有这些添加到锚点。然后它会显示在真实空间中并固定在适当的位置。

let scene = SCNScene(named: "name of your scn asset")!
          if let sceneNode = scene.rootNode.childNode(withName: "name of the scn assets root node", recursively: true){
             sceneNode.position = cameraPosition //this'll place the object at the camera's position
              sceneView.scene.rootNode.addChildNode(sceneNode)

func 渲染器(_渲染器:SCNSceneRenderer,didAdd 节点:SCNNode,锚点:ARAnchor){

        // Place content only for anchors found by plane detection.
        guard let planeAnchor = anchor as? ARPlaneAnchor else { return }
    
        let planeNode = SCNNode()
    
        planeNode.position = SCNVector3(x: planeAnchor.center.x, y: 0, z: planeAnchor.center.z)
    
        planeNode.transform = SCNMatrix4MakeRotation(-.pi/2, 1, 0, 0)
        
        // Add the visualization to the ARKit-managed node so that it tracks
        // changes in the plane anchor as plane estimation continues.
        node.addChildNode(planeNode)
}

更棘手的一点是让它出现在给定的 GPS 位置。应用程序启动时,设备的本地空间位于 0,0。您必须能够将 GPS 坐标转换为现实世界坐标,然后将其转换为设备的本地空间。有很多网站都有相关的数学计算,尽管我还无法让它发挥作用。

© www.soinside.com 2019 - 2024. All rights reserved.