티스토리 뷰
저번 포스팅에는 face tracking을 해보았는데요, 이어서 eye tracking을 해보겠습니다.
이렇게 제가 눈을 깜박일때마다 로봇박스 눈도 따라오게 해주겠습니다.

[1] eyeLeftNode, eyeRightNode를 가져오기
robotHead.scn 파일을 들어가보면
eyeLeft랑 eyeRight 라는 childNode가 있습니다.

이런식으로 가져올 수 있습니다.
let resourceName = "robotHead"
let contentNode = SCNReferenceNode(named: resourceName)
let eyeLeftNode = contentNode.childNode(withName: "eyeLeft", recursively: true)
let eyeRightNode = contentNode.childNode(withName: "eyeRight", recursively: true)
[2] blendShapes
ARFaceAnchor에는 얼굴 표정과 관련된 정보를 주는 blendShapes 딕셔너리가 있습니다.
이 딕셔너리의 키값 을 살펴보면 눈, 코, 입, 턱 등에 관한 다양한 정보를 주는 것 같아요 👍
저는 눈깜박이는 정보를 얻어야하니까 eyeBlinkLeft랑 eyeBlinkRight 라는 키값을 사용해줄것입니다
왼쪽 눈을 다 뜨면 eyeBlinkLeft의 값은 0,
왼쪽 눈을 다 감으면 eyeBlinkLeft의 값은 1 입니다.
눈을 깜박깜박 거리면 0에서 1 사이의 값을 주겠죠?!

[3] node가 업데이트 될때마다 eyeLeftNode, eyeRightNode의 scale값 변경하기
renderer(_:didUpdate:for:) 이 메소드안에서 업데이트 시켜주면 됩니다.
그 전에 scale 값에 따라서 모양이 어떻게 달라지는 지 살펴볼게요-!
1) scale.x
scale.x가 1일때
eyeLeftNode.scale.x = 1
eyeRightNode.scale.x = 1

scale.x가 0일때
eyeLeftNode.scale.x = 0
eyeRightNode.scale.x = 0

2) scale.y
scale.y가 1일때
eyeLeftNode.scale.y = 1
eyeRightNode.scale.y = 1

scale.y가 0일때
eyeLeftNode.scale.y = 0
eyeRightNode.scale.y = 0

(막 번쩍번쩍 거림)
3) scale.z
scale.z = 1일때
eyeLeftNode.scale.z = 1
eyeRightNode.scale.z = 1

scale.z = 0일때
eyeLeftNode.scale.z = 0
eyeRightNode.scale.z = 0

아무튼 scale이 1이여야지 기존 형태를 유지합니다. (눈뜬 모양)
근데 eyeBlink가 1일때는 눈감은 상태이니까
scale.z = 1 - eyeBlink <- 이렇게 값을 업데이트 시켜줍니다.

최종코드는 이렇게 되겠습니다-!
import UIKit | |
import SceneKit | |
import ARKit | |
class ViewController: UIViewController { | |
@IBOutlet var sceneView: ARSCNView! | |
var contentNode: SCNNode? | |
lazy var eyeLeftNode = contentNode?.childNode(withName: "eyeLeft", recursively: true) | |
lazy var eyeRightNode = contentNode?.childNode(withName: "eyeRight", recursively: true) | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
setupSceneView() | |
} | |
override func viewWillAppear(_ animated: Bool) { | |
super.viewWillAppear(animated) | |
} | |
override func viewDidAppear(_ animated: Bool) { | |
super.viewDidAppear(animated) | |
resetTracking() | |
} | |
override func viewWillDisappear(_ animated: Bool) { | |
super.viewWillDisappear(animated) | |
sceneView.session.pause() | |
} | |
private func setupSceneView() { | |
sceneView.delegate = self | |
} | |
private func resetTracking() { | |
let configuration = ARFaceTrackingConfiguration() | |
sceneView.session.run(configuration, | |
options: [.resetTracking, .removeExistingAnchors]) | |
} | |
} | |
extension ViewController: ARSCNViewDelegate { | |
func renderer(_ renderer: SCNSceneRenderer, nodeFor anchor: ARAnchor) -> SCNNode? { | |
guard anchor is ARFaceAnchor else { return nil } | |
let resourceName = "robotHead" | |
self.contentNode = SCNReferenceNode(named: resourceName) | |
return contentNode | |
} | |
func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { | |
guard let faceAnchor = anchor as? ARFaceAnchor else { return } | |
let blendShapes = faceAnchor.blendShapes | |
if let eyeBlinkLeft = blendShapes[.eyeBlinkLeft] as? Float, let eyeBlinkRight = blendShapes[.eyeBlinkRight] as? Float { | |
eyeLeftNode?.scale.z = 1 - eyeBlinkLeft | |
eyeRightNode?.scale.z = 1 - eyeBlinkRight | |
} | |
} | |
} |
(참고로 애플예제를 보면 턱 트래킹(jaw tracking) 도 되어있습니다)
'🍏 > ARKit' 카테고리의 다른 글
[ARKit] Xcode에서 dae파일을 scn파일로 convert하기 (0) | 2020.05.31 |
---|---|
[ARKit] 3D Content 직접 만들기 (scn파일 만들기) (0) | 2020.05.29 |
[ARKit] Face Tracking 앱 만들기 (2) - ARFaceAnchor, SCNReferenceNode, renderer (0) | 2020.05.28 |
[ARKit] Face Tracking 앱 만들기 (1) - ARFaceTrackingConfiguration (0) | 2020.05.26 |
[iOS-ARKit] SCNText, SCNBox, SCNSphere 를 띄워보자 (0) | 2019.05.18 |
eungding님의
글이 좋았다면 응원을 보내주세요!
- Total
- Today
- Yesterday
- ribs
- Python Type Hint
- 플러터 얼럿
- flutter build mode
- github actions
- 플러터 싱글톤
- Flutter 로딩
- Django FCM
- SerializerMethodField
- METAL
- Flutter getter setter
- PencilKit
- Flutter Text Gradient
- Dart Factory
- Django Heroku Scheduler
- Flutter Clipboard
- flutter 앱 출시
- cocoapod
- drf custom error
- 장고 Custom Management Command
- flutter deep link
- DRF APIException
- Flutter Spacer
- flutter dynamic link
- Sketch 누끼
- 구글 Geocoding API
- Watch App for iOS App vs Watch App
- 장고 URL querystring
- ipad multitasking
- Django Firebase Cloud Messaging
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |