我怎样才能绝对地获得 ARAnchor 的偏航、俯仰和滚动?

How can I get the yaw, pitch, roll of an ARAnchor in absolute terms?

几天来我一直在努力解决这个问题。

给定一个基于 ARKit 的应用程序,我可以在其中跟踪用户的面部,我如何才能从其锚点获得面部的绝对旋转?

我可以得到 ARAnchor 的转换,它是 simd_matrix4x4。 有很多关于如何从该矩阵(它是第 3 列)中获取位置的信息,但没有关于旋转的信息!

我希望能够通过传递 YAW、PITCH 和 ROLL 来控制应用程序外部的 3D 对象。

我最近尝试的东西确实有些效果:

let arFrame = session.currentFrame!
guard let faceAnchor = arFrame.anchors[0] as? ARFaceAnchor else { return }

let faceMatrix = SCNMatrix4.init(faceAnchor.transform)
let node = SCNNode()

node.transform = faceMatrix
let rotation = node.worldOrientation

rotation.x .y 和 .z 具有我可以使用的值,但是当我移动我的 phone 时,值会改变 。例如,如果我转动 180˚ 并继续注视 phone,则值会根据 phone.

的位置发生剧烈变化

我尝试在 ARConfiguration 中更改世界对齐方式,但这并没有什么不同。

我读错参数了吗?这本来应该容易得多!

我了解到您使用的是前置摄像头和 ARFaceTrackingConfiguration,这不应该为您提供绝对值。我会尝试为后置摄像头配置第二个 ARSessionARWorldTrackingConfiguration 确实提供绝对值。最终解决方案可能需要来自两个 ARSession 的值。我还没有测试这个假设,但它似乎是唯一的方法。

更新 引自 ARWorldTrackingConfiguration -

The ARWorldTrackingConfiguration class tracks the device's movement with six degrees of freedom (6DOF): specifically, the three rotation axes (roll, pitch, and yaw), and three translation axes (movement in x, y, and z). This kind of tracking can create immersive AR experiences: A virtual object can appear to stay in the same place relative to the real world, even as the user tilts the device to look above or below the object, or moves the device around to see the object's sides and back.

显然,其他跟踪配置具有此功能。

我想通了...

获得面部锚点后,需要对其变换矩阵和相机变换进行一些计算。

像这样:

let arFrame = session.currentFrame!
guard let faceAnchor = arFrame.anchors[0] as? ARFaceAnchor else { return }

let projectionMatrix = arFrame.camera.projectionMatrix(for: .portrait, viewportSize: self.sceneView.bounds.size, zNear: 0.001, zFar: 1000)
let viewMatrix = arFrame.camera.viewMatrix(for: .portrait)

let projectionViewMatrix = simd_mul(projectionMatrix, viewMatrix)
let modelMatrix = faceAnchor.transform
let mvpMatrix = simd_mul(projectionViewMatrix, modelMatrix)

// This allows me to just get a .x .y .z rotation from the matrix, without having to do crazy calculations
let newFaceMatrix = SCNMatrix4.init(mvpMatrix)
let faceNode = SCNNode()
faceNode.transform = newFaceMatrix
let rotation = vector_float3(faceNode.worldOrientation.x, faceNode.worldOrientation.y, faceNode.worldOrientation.z)

rotation.x .y 和 .z 将 return 面部的俯仰、偏航、滚动(分别)

我添加了一个小的乘数并将轴的 2 反转,所以它最终是这样的:

yaw = -rotation.y*3
pitch = -rotation.x*3
roll = rotation.z*1.5

呸!