ARkit
ARFaceTrackingConfiguration()
2료일
2023. 7. 12. 03:55
1. 먼저 기기에서 지원을 확인을 하는지 Appdelgate에서 확인을 한다.
if !ARFaceTrackingConfiguration.isSupported {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()) {
let alert = UIAlertController(title: "Unsupported Device", message: "This app requires TrueDepth Camera with iOS 11.0+", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Close", style: .default) { action in
exit(0)
})
self.window?.rootViewController?.present(alert, animated: true)
}
}
2. ViewWillApear 수정
let configuration = ARFaceTrackingConfiguration()
// TODO: 3) 얼굴 인식을 사용하는 앱은 세션을 시작할 때 마다 트래킹을 리셋해주고, 존재하는 anchor를 지워주어야 한다.
sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
뷰가 appear될때마다 트레킹과 존재 anchor reset해준다
3. render(_ : nodeFor) delegate 메서드 구현
var contentNode: SCNReferenceNode? = nil
// TODO: 4) 인식된 Face Anchor에 3D 콘텐트가 붙은 SCNNode를 붙여준다.
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? {
guard anchor is ARFaceAnchor else {
return nil
}
// Main Bundle에서 로봇 url가져오기
guard let resourceUrl = Bundle.main.url(forResource: "robotHead", withExtension: "scn", subdirectory: "Models.scnassets") else {
return nil
}
// 해당 URL로 SCNReferenceNode 생성
guard let contentNode = SCNReferenceNode(url: resourceUrl) else {
return nil
}
self.contentNode = contentNode
self.contentNode?.load()
// contentNode로부터 왼쪽, 오른쪽 눈 Node를 가져오기
return self.contentNode
}
ARFaceAnchor에서는 여러 얼굴이 있을 경우 가장 크거나 가장 선명하게 인식할 수 있는 얼굴을 고른다.
ARKit은 앵커의 SceneKit 노드를 관리하고 각 프레임에서 해당 노드의 위치와 방향을 업데이트하므로 해당 노드에 추가하는 모든 SceneKit 콘텐츠는 사용자의 얼굴의 위치와 방향을 자동으로 tracking
ARSCNViewDeleagate의 함수인데 이 함수를 통해 ARAnchor를 기반으로 새로운 노드생성
4. 왼쪽눈 오른쪽눈 각각을 노드로 생성후 업데이트 render함수생성
var leftEyeNode: SCNNode? {
return contentNode?.childNode(withName: "eyeLeft", recursively: true)
}
// 로봇 오른쪽 눈
var rightEyeNode: SCNNode? {
return contentNode?.childNode(withName: "eyeRight", recursively: true)
}
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) {
guard let anchor = anchor as? ARFaceAnchor else { return }
if let leftEyeBlink = anchor.blendShapes[.eyeBlinkLeft] as? Float,
let rightEyeBlink = anchor.blendShapes[.eyeBlinkRight] as? Float {
leftEyeNode?.scale.z = 1 - leftEyeBlink
rightEyeNode?.scale.z = 1 - rightEyeBlink
}
}
ARKit은 사용자가 눈을 깜빡이고, 말하고, 다양한 표현을 할 때에도 사용자의 얼굴 모양에 맞게 얼굴 메쉬를 업데이트!!
표시된 얼굴 모델이 사용자의 표현을 따르도록 하려면, renderer(_:didUpdate:for:) delegate 콜백에서 업데이트된 얼굴 메쉬를 검색한다.