Search code examples
iosaugmented-realityarkitrealitykittruedepth-camera

Why does ARFaceAnchor have negative Z position?


I am using ARKit's ARFaceTrackingConfiguration with ARConfiguration.WorldAlignment.camera alignment, but I found that the documentation (seemingly) does not reflect the reality;

Based on the excerpt of documentation below, I would expect that the face anchor's transform is expressed in right handed coordinate system. However, when I tried moving my head, I noticed that the Z coordinate of the face anchor is always negative (i.e. faceAnchor.transform.columns.3.z < 0). Note that moving head in the X and Y directions corresponds to expected outcome (unlike Z coordinate).

Camera alignment defines a coordinate system based on the native sensor orientation of the device camera. Relative to a AVCaptureVideoOrientation.landscapeRight-oriented camera image, the x-axis points to the right, the y-axis points up, and the z-axis points out the front of the device (toward the user).

I want the transform to behave as per the documentation, i.e. the Z coordinate of face anchor should be positive given that documentation says "the z-axis points out the front of the device (toward the user)". So far it seems the Z-axis points out the back of the device…

Am I missing something obvious?

I tried to repair the rotation by the following code, but I am not sure if it's correct way to fix this:

// Repair rotation
let oldFaceRotation = simd_quatf(face.transform) // get quaternion from 
let repairedFaceRotation = simd_quatf(ix: oldFaceRotation.axis.y, iy: oldFaceRotation.axis.x, iz: -oldFaceRotation.axis.z, r: oldFaceRotation.real)

// Repair translation
var repairedPosition = face.transform.columns.3
repairedPosition.z *= -1

// Combine
var correctedFaceTransform = float4x4(repairedFaceRotation)
correctedFaceTransform.columns.3 = repairedPosition

Solution

  • It seems quite obvious:

    When ARSession is running and ARCamera begins tracking environment, it places WorldOriginAxis in front of your face at (x: 0, y: 0, z: 0). Just check it using:

     sceneView.debugOptions = [.showWorldOrigin]
    

    So your face's position must be at positive part of Z axis of World Coordinates.

    enter image description here

    Thus, ARFaceAnchor will be placed at positive Z-axis direction, as well.

    enter image description here

    And when you use ARFaceTrackingConfiguration vs ARWorldTrackingConfiguration there's two things to consider:

    • Rear Camera moves towards objects along negative Z-axes (positive X-axis is on the right).

    • Front Camera moves towards faces along positive Z-axes (positive X-axis is on the left).

    Hence, when you are "looking" through TrueDepth Camera, a 4x4 Matrix is mirrored.