首页 文章

ARKit 1.5 如何获得垂直平面的旋转

提问于
浏览
7

我正在尝试垂直平面,并且尝试在基于垂直平面的正确旋转下将节点放置在墙上。

这是点击的垂直平面的 ARHitTestResult:

let hitLocation = sceneView.hitTest(touchPoint, types: .existingPlaneUsingExtent)

我尝试了以下方法:

let hitRotation = hitLocation.first?.worldTransform.columns.2

let anchor = hitLocation.first?.anchor
let hitRotation = anchor?.transform.columns.2

他们俩似乎都没有工作。

这就是我希望做的:

boardNode.eulerAngles = SCNVector3((hitRotation?.x)!, (hitRotation?.y)!, 0)

如果有人可以帮助我解决这个问题,我将不胜感激,因为我还没有在 ARKit 上找到很多教程。

编辑

所以这是起作用的(感谢 Josh):

let hit = sceneView.hitTest(touchPoint, types: .existingPlaneUsingExtent)
let planeAnchor = hit.first?.anchor as? ARPlaneAnchor

guard let anchoredNode =  sceneView.node(for: planeAnchor!) else { return }

let anchorNodeOrientation = anchoredNode.worldOrientation

boardNode.eulerAngles.y = .pi * anchorNodeOrientation.y

注意:在这种情况下,.worldOrientation 比.rotation 更准确。

1 回答

  • 6

    这是您要找的东西吗?在这里,我将屏幕中心用于 CGPoint 值,但是您可以使用 touch 等:

    func addObjectToScreen() {
    
            if let hit = self.sceneView?.hitTest(self.viewCenter, types: [.existingPlaneUsingExtent]).last {
    
                let hitTestTransform = SCNMatrix4(hit.worldTransform)
    
                let vector = SCNVector3Make(hitTestTransform.m41, hitTestTransform.m42, hitTestTransform.m43)
    
                node.position = vector
    
                return
            }
    }
    

    **更新:**如果您不希望旋转与“平面”关联的节点,则可以像这样:

    func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
    
          print(node.rotation)
    
    }
    

    然后根据需要使用它?

    进一步更新:

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    
     /*
     1. Get The Current Touch Location
     2. Check That We Have Touched A Valid Node
     3. Check That Our Touched Object Is An ARPlane Anchor
     */
    
     guard let touchLocation = touches.first?.location(in: augmentedRealityView),
     let hitTest = augmentedRealityView.hitTest(touchLocation, types: .existingPlaneUsingExtent).first,
     let planeAnchor = hitTest.anchor as? ARPlaneAnchor
     else {
    
     // No Valid Plane Has Been Detected So Hide The Plane Information Label
    
     return
    
     }
    
        //We Have A Valid Plane So Display It's Current Info
        guard let anchoredNode =  augmentedRealityView.node(for: planeAnchor) else { return }
        print(anchoredNode.rotation)
    
     }
    

相关问题