将 ARFaceAnchor 从左手坐标系翻转到右手坐标系
Flip ARFaceAnchor from left-handed to right-handed coordinate system
通过打印 faceAnchor.transform.columns.3
进行一些测试后,在 SO: and Apple's documentation: ARFaceAnchor 中挖掘,我意识到 z 轴实际上是翻转的,它不是文档中的右手坐标系。 ARFaceAnchor 声明坐标:
the positive x direction points to the viewer’s right (that is, the face’s own left), the positive y direction points up (relative to the face itself, not to the world), and the positive z direction points outward from the face (toward the viewer)
Sarasvati 给出了改造建议:
func faceAnchorPoseToRHS(_ mat: float4x4) -> float4x4 {
let correctedPos = float4(x: mat.columns.3.x, y: mat.columns.3.y, z: -mat.columns.3.z, w: 1)
let quat = simd_quatf(mat)
let newQuat = simd_quatf(angle: -quat.angle, axis: float3(quat.axis.x, quat.axis.y, -quat.axis.z))
var newPose = float4x4(newQuat)
newPose.columns.3 = correctedPos
return newPose
}
基于 Andy Fedoroff 的更新:
extension ViewController: ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let faceAnchor = anchor as? ARFaceAnchor else { return }
currentFaceAnchor = faceAnchor
if node.childNodes.isEmpty, let contentNode = selectedContentController.renderer(renderer, nodeFor: faceAnchor) {
node.addChildNode(contentNode)
}
selectedContentController.session = sceneView?.session
selectedContentController.sceneView = sceneView
}
/// - Tag: ARFaceGeometryUpdate
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard anchor == currentFaceAnchor,
let contentNode = selectedContentController.contentNode,
contentNode.parent == node
else { return }
sceneView.session.currentFrame!.anchors.first!.transform
print(currentFaceAnchor!.transform.columns.3)
selectedContentController.session = sceneView?.session
selectedContentController.sceneView = sceneView
selectedContentController.renderer(renderer, didUpdate: contentNode, for: anchor)
}
}
但是,我打印了 faceAnchor.transform.columns.3
并使用 True Depth 相机获得了 z 底片。下面显示 x,y,z,w 轴:
关于如何校正 z 轴有什么建议吗?提前谢谢你
首先,让我们看看默认矩阵值是什么。
单位矩阵
这是一个 Identity 4x4 matrix
的默认值。
如果您需要有关 4x4 matrices
元素的更多信息,请阅读 this post。
// 0 1 2 3
┌ ┐
| 1 0 0 0 | x
| 0 1 0 0 | y
| 0 0 1 0 | z
| 0 0 0 1 |
└ ┘
位置镜像
要翻转实体的 Z axis
和 X axis
,以便将轴从面部跟踪环境重新定向到世界跟踪环境,请使用以下形式的 4x4 transform matrix
。
// 0 1 2 3
┌ ┐
| -1 0 0 0 | x
| 0 1 0 0 | y
| 0 0 -1 0 | z
| 0 0 0 1 |
└ ┘
旋转镜像
在4x4 transform matrices
中旋转是combination of scale and skew
。要选择右旋转的方向,顺时针 (CW) 或逆时针 (CCW) 使用 +
或 -
表示 cos
表达式。
这是正 Z 轴旋转表达式 (CCW)。
正 +cos(a)
:
┌ ┐
| cos -sin 0 0 |
| sin cos 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
└ ┘
这是负 Z 轴旋转表达式 (CW)。
否定-cos(a)
:
┌ ┐
|-cos -sin 0 0 |
| sin -cos 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
└ ┘
通过打印 faceAnchor.transform.columns.3
进行一些测试后,在 SO:
the positive x direction points to the viewer’s right (that is, the face’s own left), the positive y direction points up (relative to the face itself, not to the world), and the positive z direction points outward from the face (toward the viewer)
Sarasvati 给出了改造建议:
func faceAnchorPoseToRHS(_ mat: float4x4) -> float4x4 {
let correctedPos = float4(x: mat.columns.3.x, y: mat.columns.3.y, z: -mat.columns.3.z, w: 1)
let quat = simd_quatf(mat)
let newQuat = simd_quatf(angle: -quat.angle, axis: float3(quat.axis.x, quat.axis.y, -quat.axis.z))
var newPose = float4x4(newQuat)
newPose.columns.3 = correctedPos
return newPose
}
基于 Andy Fedoroff 的更新:
extension ViewController: ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) {
guard let faceAnchor = anchor as? ARFaceAnchor else { return }
currentFaceAnchor = faceAnchor
if node.childNodes.isEmpty, let contentNode = selectedContentController.renderer(renderer, nodeFor: faceAnchor) {
node.addChildNode(contentNode)
}
selectedContentController.session = sceneView?.session
selectedContentController.sceneView = sceneView
}
/// - Tag: ARFaceGeometryUpdate
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard anchor == currentFaceAnchor,
let contentNode = selectedContentController.contentNode,
contentNode.parent == node
else { return }
sceneView.session.currentFrame!.anchors.first!.transform
print(currentFaceAnchor!.transform.columns.3)
selectedContentController.session = sceneView?.session
selectedContentController.sceneView = sceneView
selectedContentController.renderer(renderer, didUpdate: contentNode, for: anchor)
}
}
但是,我打印了 faceAnchor.transform.columns.3
并使用 True Depth 相机获得了 z 底片。下面显示 x,y,z,w 轴:
关于如何校正 z 轴有什么建议吗?提前谢谢你
首先,让我们看看默认矩阵值是什么。
单位矩阵
这是一个 Identity 4x4 matrix
的默认值。
如果您需要有关 4x4 matrices
元素的更多信息,请阅读 this post。
// 0 1 2 3
┌ ┐
| 1 0 0 0 | x
| 0 1 0 0 | y
| 0 0 1 0 | z
| 0 0 0 1 |
└ ┘
位置镜像
要翻转实体的 Z axis
和 X axis
,以便将轴从面部跟踪环境重新定向到世界跟踪环境,请使用以下形式的 4x4 transform matrix
。
// 0 1 2 3
┌ ┐
| -1 0 0 0 | x
| 0 1 0 0 | y
| 0 0 -1 0 | z
| 0 0 0 1 |
└ ┘
旋转镜像
在4x4 transform matrices
中旋转是combination of scale and skew
。要选择右旋转的方向,顺时针 (CW) 或逆时针 (CCW) 使用 +
或 -
表示 cos
表达式。
这是正 Z 轴旋转表达式 (CCW)。
正 +cos(a)
:
┌ ┐
| cos -sin 0 0 |
| sin cos 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
└ ┘
这是负 Z 轴旋转表达式 (CW)。
否定-cos(a)
:
┌ ┐
|-cos -sin 0 0 |
| sin -cos 0 0 |
| 0 0 1 0 |
| 0 0 0 1 |
└ ┘