ARKit 1.5 如何获取垂直平面的旋转
ARKit 1.5 how to get the rotation of a vertical plane
我正在试验垂直平面,我试图将一个节点放置在墙上,并根据该垂直平面进行正确的旋转。
这是被点击的垂直平面的 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 更准确,只是想提一下。
这是您要找的吗?这里我使用屏幕中心作为 CGPoint 值,但你可以使用触摸等:
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)
}
我正在试验垂直平面,我试图将一个节点放置在墙上,并根据该垂直平面进行正确的旋转。
这是被点击的垂直平面的 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 更准确,只是想提一下。
这是您要找的吗?这里我使用屏幕中心作为 CGPoint 值,但你可以使用触摸等:
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)
}