【Swift】【ARKit】ARkitのFaceTrackingで楽○カードマンになる!
はじめに
前回の記事「【Swift】1週間、iOSアプリを作ってみた」でARKitを触ってみて色々できて楽しいなと感じていた時に、iPhone XがあるのにFace Trackingを触ってみないのもあれだなーと感じてAppleの公式 サンプルを実際に動かしてみた。動かしてみると、三種類のことができて能面のようなマスクをつけれたり目の位置にARと書かれた文字のオブジェクトを置いたりロボットの頭になったりできた。 ARの文字を目元につけられるサンプルを見て、楽○カードマンも簡単にできると感じたのでやって見た(笑)
ソースコード
すべてViewControllerに記述しているので綺麗なコードではありません。 Appleのサンプルを簡単に使いたいところをまとめただけなのでサンプルを参考にしてください。
import UIKit import SceneKit import ARKit class ViewController: UIViewController, ARSessionDelegate, ARSCNViewDelegate { @IBOutlet var sceneView: ARSCNView! private var faceNode = SCNNode() private var virtualFaceNode = SCNNode() private let serialQueue = DispatchQueue(label: "com.example.apple-samplecode.ARKitFaceExample.serialSceneKitQueue") var session: ARSession { return sceneView.session } // 起動時に一度だけ実行される override func viewDidLoad() { super.viewDidLoad() sceneView.delegate = self sceneView.session.delegate = self sceneView.automaticallyUpdatesLighting = true // 下の一行は、ARFaceTrackingがXcodeで有効なデバイスが選択されていなければエラーが出る let device = sceneView.device! let glassesGeometry = ARSCNFaceGeometry(device: device)! glassesGeometry.firstMaterial!.colorBufferWriteMask = [] virtualFaceNode.geometry = glassesGeometry // 3Dコンテンツを探してロード let url = Bundle.main.url(forResource: "rakutenCard", withExtension: "scn", subdirectory: "Models.scnassets")! let node = SCNReferenceNode(url:url)! node.load() // 3dコンテンツを目元に追加 let faceOverlayContent = node virtualFaceNode.addChildNode(faceOverlayContent) resetTracking() } // 画面が表示された直後に実行される override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // スリープに入らないようにする UIApplication.shared.isIdleTimerDisabled = true // トラッキングの初期化をする resetTracking() } // 画面が非表示になったら実行される override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) sceneView.session.pause() } func resetTracking() { let configuration = ARFaceTrackingConfiguration() configuration.isLightEstimationEnabled = true session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) } private func setupFaceNodeContent() { for child in faceNode.childNodes { child.removeFromParentNode() } faceNode.addChildNode(virtualFaceNode) } // トラッキング開始 func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { print("トラッキング開始") faceNode = node serialQueue.async { self.setupFaceNodeContent() } } // 更新 func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { guard let faceAnchor = anchor as? ARFaceAnchor else { return } //virtualFaceNode.update(withFaceAnchor: faceAnchor) let geometry = virtualFaceNode.geometry as! ARSCNFaceGeometry geometry.update(from: faceAnchor.geometry) } // エラー処理 func session(_ session: ARSession, didFailWithError error: Error) { guard error is ARError else { return } } func sessionInterruptionEnded(_ session: ARSession) { DispatchQueue.main.async { self.resetTracking() } } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
実機での確認
ARkitのFace Trackingは画像などの人物にも有効です。
下記の画像は、Googleで画像検索した人を楽○カードマンにして見ました。
自分の顔でも実際動作し動きにも対応しているので試して見てはいかがでしょうか
おわりに
今回作った楽○カードマンになれるアプリはとても簡単に実装できました。 今回はXcodeを使って政策しましたが、Unityなどを使うともっと様々なオブジェクトを容易に顔面に貼り付けたり、顔をつかったゲームを作れそうですね。 ARkit 2が発表されており、FaceTrackingでは舌と目線が検知できるようになるらしいです。 これからどんどん活性化していくAR,VR,MRにはまだまだ注目していきたいところですね。
参考
はじめにでも書いたようにApple のサンプルです。