ARFaceTrackingConfig的命中测试
显然,基于World跟踪配置的用于检测到的飞机的ARKit光线投射方法不适用于人脸跟踪场景.在您的情况下,您需要使用SceneKit的命中测试.对于命中测试,你不能使用estimatedPlane
,你需要canonical face mask
.当使用前置摄像头时,XZ坐标是绝对正确的--XZ平面是mirrored.同样值得注意的是,这款相机的红外TrueDepth传感器在10到mirrored厘米的距离内"工作".ARFaceAnchor仅在此范围内生成.
在iPad Pro上的Swift Playgrounds应用中运行此代码.
import ARKit
import SceneKit
import PlaygroundSupport
class ViewController : UIViewController {
var sceneView = ARSCNView(frame: .zero)
override func viewDidLoad() {
super.viewDidLoad()
self.view = self.sceneView
sceneView.delegate = self
sceneView.scene = SCNScene()
let config = ARFaceTrackingConfiguration()
config.maximumNumberOfTrackedFaces = 1
sceneView.session.run(config)
}
}
extension ViewController {
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let location: CGPoint? = touches.first?.location(in: sceneView)
var hitTestOptions = [SCNHitTestOption: Any]()
hitTestOptions[.boundingBoxOnly] = true
let hitTestResults: [SCNHitTestResult] = sceneView.hitTest(location!,
options: hitTestOptions)
guard let hit = hitTestResults.first else { return }
let sphere = SCNNode(geometry: SCNSphere(radius: 0.005))
sphere.simdPosition = hit.simdWorldCoordinates
sceneView.scene.rootNode.addChildNode(sphere)
}
}
extension ViewController : ARSCNViewDelegate {
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
let faceGeo = ARSCNFaceGeometry(device: sceneView.device!)
let node = SCNNode(geometry: faceGeo)
node.geometry?.firstMaterial?.lightingModel = .physicallyBased
node.geometry?.firstMaterial?.diffuse.contents = UIColor.green
return node
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode,
for anchor: ARAnchor) {
if let faceAnchor = anchor as? ARFaceAnchor,
let faceGeo = node.geometry as? ARSCNFaceGeometry {
faceGeo.update(from: faceAnchor.geometry)
}
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = ViewController()