50行で目線トラッキング（iPhone）

 ![Xcode-13.1](https://img.shields.io/badge/Xcode-13.1-brightgreen) ![Swift-5.5.1](https://img.shields.io/badge/Swift-5.5.1-brightgreen) ![iOS-15.1](https://img.shields.io/badge/iOS-15.1-brightgreen) 

## はじめに
こちらの記事を見て目線トラッキングが面白そうだなと思いました。
[目線でブラウザをスクロールするアプリを作ってみた](https://dev.classmethod.jp/articles/eye-scrollable-web-view/)

調べてみると 50 行くらいで下記ができました（動作確認は iOS 15.1 の iPhone 12 mini）。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">目線トラッキングができてるようなできてないような👀<br>コード量50行！ <a href="https://t.co/6uiApUJnPn">pic.twitter.com/6uiApUJnPn</a></p>&mdash; am10 (@am103141592) <a href="https://twitter.com/am103141592/status/1487063754252554246?ref_src=twsrc%5Etfw">January 28, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 実装
とりあえずソース。

```swift
import UIKit
import ARKit

final class ViewController: UIViewController {

    private let session = ARSession()
    private var lookAtPointView: UIImageView = {
        let image = UIImageView(image: .init(systemName: "eye"))
        image.frame = .init(origin: .zero, size: CGSize(width: 30, height: 30))
        image.contentMode = .scaleAspectFit
        return image
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(lookAtPointView)
        session.delegate = self
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let configuration = ARFaceTrackingConfiguration()
        configuration.isLightEstimationEnabled = true
        session.run(configuration, options: [.resetTracking, .removeExistingAnchors])
    }
}

extension ViewController: ARSessionDelegate {

    func session(_ session: ARSession, didUpdate frame: ARFrame) {
        guard let faceAnchor = frame.anchors.first(where: { $0 is ARFaceAnchor }) as? ARFaceAnchor else {
            return
        }
        let lookingPoint = frame.camera.projectPoint(faceAnchor.lookAtPoint,
                                                     orientation: .portrait,
                                                     viewportSize: view.bounds.size)
        DispatchQueue.main.async {
            self.lookAtPointView.center = lookingPoint
        }
    }
}
```

これだけで目線トラッキングぽいことができます:clap:

## 必要条件
`ARKit` の `ARFaceTrackingConfiguration` を利用するので TrueDepth カメラを搭載した端末（iPhone X 以降？）が必要です。

[ドキュメント：ARFaceTrackingConfiguration](https://developer.apple.com/documentation/arkit/arfacetrackingconfiguration)

## やりたかったこと
ピアノ演奏中の楽譜への目線とか本読むのが速い人の目線の動きとかを iPhone で見れたらおもしろいと思った。

が、厳密に目線を取得はできなかったのであきらめました。。。（どちらかというと顔の向きの取得？）

[ドキュメント：ARFaceAnchor](https://developer.apple.com/documentation/arkit/arfaceanchor)

## つくったもの
上記のものは作れなさそうでしたが目線トラッキングはおもしろいので何か他のものを作れないかと思い色々考えてみました。

調べてみると `ARFaceAnchor.BlendShapeLocation` で左右の瞬きなどが取れそうです。  
[ドキュメント：ARFaceAnchor.BlendShapeLocation](https://developer.apple.com/documentation/arkit/arfaceanchor/blendshapelocation/2928261-eyeblinkleft)

### １つ目
瞬きで撃つシューティングゲーム（音声あり）。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">やりたいことできなそうだったから路線変更して瞬きで撃つシューティングつくった😉 <a href="https://t.co/nDSIIEMBz3">pic.twitter.com/nDSIIEMBz3</a></p>&mdash; am10 (@am103141592) <a href="https://twitter.com/am103141592/status/1487368204590940161?ref_src=twsrc%5Etfw">January 29, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

### ２つ目
目線をマウスカーソル瞬きをクリックに対応させた PC のような操作ができるなにか。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">目線をマウスカーソルまばたきをクリックに対応させることでiPhoneでPCのような操作を実現😉 <a href="https://t.co/9KFblAJ5bp">pic.twitter.com/9KFblAJ5bp</a></p>&mdash; am10 (@am103141592) <a href="https://twitter.com/am103141592/status/1487924375970287617?ref_src=twsrc%5Etfw">January 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## おわりに
目線トラッキングおもしろそうなのでなにか使えそうなのですが私の発想ではなかなかむずかしかったです。

なにかに使えそう:thinking:

## 参考
* [目線でブラウザをスクロールするアプリを作ってみた](https://dev.classmethod.jp/articles/eye-scrollable-web-view/)
* [ドキュメント：ARFaceTrackingConfiguration](https://developer.apple.com/documentation/arkit/arfacetrackingconfiguration)
* [ドキュメント：ARFaceAnchor](https://developer.apple.com/documentation/arkit/arfaceanchor)