Как преобразовать из локальных координат в координаты пространства экрана в ARSCNView? - ios


1

Я хочу получить угловые координаты плоскости, которую ARKit идентифицировал в ARSCNView экрана ARSCNView.

Я начал с адаптации примера Apple для создания самолетов, поэтому у меня есть класс Plane:

class Plane : SCNNode {

    var anchor : ARPlaneAnchor

    init(anchor : ARPlaneAnchor) {
        self.anchor = anchor
        super.init()

        self.geometry = SCNPlane(width: CGFloat(Float(anchor.extent.x)), height: CGFloat(anchor.extent.z))
        self.rotation = SCNVector4Make(1.0, 0.0, 0.0, -Float.pi/2.0)
        let material = SCNMaterial()
        material.diffuse.contents = UIColor.yellow
        material.specular.contents = UIColor.white
        self.geometry?.firstMaterial = material
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("Error")
    }

    func update(anchor: ARPlaneAnchor) {
        self.anchor = anchor
        if let plane = self.geometry as? SCNPlane {
            plane.width = CGFloat(anchor.extent.x)
            plane.height = CGFloat(anchor.extent.z)
        }
    }
}

И методы ARSCNViewDelegate в контроллере представления для его идентификации и обновления:

func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    if let planeAnchor = anchor as? ARPlaneAnchor {
        let plane = Plane(anchor: planeAnchor)
        node.addChildNode(plane)
        planes[planeAnchor] = plane
        print("plane = (plane)")
    }  
}

func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
    if let planeAnchor = anchor as? ARPlaneAnchor {
        planes[planeAnchor]?.update(anchor: planeAnchor)
    }
}

func renderer(_ renderer: SCNSceneRenderer, didRemove node: SCNNode, for anchor: ARAnchor) {
    if let planeAnchor = anchor as? ARPlaneAnchor {
        planes.removeValue(forKey: planeAnchor)
    }
}

Как я понимаю, у плоскости есть собственное локальное координатное пространство в SceneKit, поэтому я хочу просто создать 4 значения SCNVector3 и преобразовать их из локального пространства Plane в пространство координат мира сцены, а из них спроектировать их в экранное пространство.

Вот как я это делаю:

   func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) {
       for (_, aPlane) in planes {
           // Vectors representing the corners of the plane
           let maxX = aPlane.anchor.extent.x/2.0
           let minX = -maxX
           let minY = aPlane.anchor.extent.z/2.0
           let maxY = -minY

           var point1 = SCNVector3Make(minX, 0.0, minY)
           var point2 = SCNVector3Make(maxX, 0.0, minY)
           var point3 = SCNVector3Make(maxX, 0.0, maxY)
           var point4 = SCNVector3Make(minX, 0.0, maxY)
//         var point1 = SCNVector3Make(minX, minY, 0.0)
//         var point2 = SCNVector3Make(maxX, minY, 0.0)
//         var point3 = SCNVector3Make(maxX, maxY, 0.0)
//         var point4 = SCNVector3Make(minX, maxY, 0.0)

           print("initial nodes ------------------")
           print("point1 = (point1)")
           print("point2 = (point2)")
           print("point3 = (point3)")
           print("point4 = (point4)")

           // Get the root node and convert the coords from the plane coord system
           let rootNode = sceneView.scene.rootNode
           point1 = rootNode.convertVector(point1, from: aPlane)
           point2 = rootNode.convertVector(point2, from: aPlane)
           point3 = rootNode.convertVector(point3, from: aPlane)
           point4 = rootNode.convertVector(point4, from: aPlane)

           print("first conversion nodes ------------------")
           print("point1 = (point1)")
           print("point2 = (point2)")
           print("point3 = (point3)")
           print("point4 = (point4)")

           // Finally, project them to the screen view
           point1 = sceneView.projectPoint(point1)
           point2 = sceneView.projectPoint(point2)
           point3 = sceneView.projectPoint(point3)
           point4 = sceneView.projectPoint(point4)
           print("final conversion nodes ------------------")
           print("point1 = (point1)")
           print("point2 = (point2)")
           print("point3 = (point3)")
           print("point4 = (point4)")
       }
   }

Однако, что бы я ни делал, когда у меня есть самолет в поле зрения, я все равно получаю координаты за пределами видимости. Я почти уверен, что это что-то простое, но сейчас я пробовал много комбинаций.

Источник
  •  20
  •  0
  • 9 мар 2020 2020-03-09 09:27:11

Ответов пока нет