[Swift/ARKit2] ライコウは松屋派、スイクンはすき家派。

# 概要

先日[初めてArkit2を触り](https://qiita.com/IZUMIRU/items/3c36f7730aff5e6305c5)、3Dモデルを用いて何かしてみたいなーと思っていたので、ちょうど良い機会だと思い、以下ツイートに便乗。エンテイの後に続き、ライコウとスイクンの牛丼業界参画を支援する。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">エンテイも吉野家とか行くんだ <a href="https://t.co/a3joquFEg1">pic.twitter.com/a3joquFEg1</a></p>&mdash; ずみ (@Zmix00) <a href="https://twitter.com/Zmix00/status/1150317635441065984?ref_src=twsrc%5Etfw">2019年7月14日</a></blockquote>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ライコウは松屋派、スイクンはすき家派か。 <a href="https://t.co/Ab1KMuY8mJ">pic.twitter.com/Ab1KMuY8mJ</a></p>&mdash; いずみーる(24);毎日個人開発🍺 (@IZUMIRU0313) <a href="https://twitter.com/IZUMIRU0313/status/1153057490763837440?ref_src=twsrc%5Etfw">2019年7月21日</a></blockquote>


# アーキテクチャ
Xcode上で[ARKit2](https://www.apple.com/jp/newsroom/2018/06/apple-unveils-arkit-2/)を利用して、Swiftでコーディングしています。コード量（ `ViewController.swift` ）は100行もないです。

![architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105093/e2ff242c-7b0d-63f3-25dc-b979222b9d1b.png)


# GitHub
全てのコードを公開しています。解説のためにコードに `What` のコメントを残しているので、見れば大体理解できると思います。

- [IZUMIRU/PokemonAR](https://github.com/IZUMIRU/PokemonAR)


# 解説
以下Qiitaが参考になりました。

- （参考）[ARKitで簡単ARやってみた](https://qiita.com/pontake-dev/items/daf4a27cccc222f9ae9d)
- （参考）[ARKit基礎まとめ - 平面検出して3Dオブジェクトを置く](https://qiita.com/developerTakata/items/8af3421a14465275a6d3)

ただたしかにクマさんは表示できるのですが、他の [free3d](https://free3d.com/) でダウンロードした3Dモデル素材ではうまくいかず、ここが一番ハマりました。時にはうまくいくものもあったので、できる素材できない素材で分けていった結果、おそらく素材そのものにテクスチャがないとダメだとわかりました。free3dにはポケモン素材はたくさんあるのですが、ほとんどテクスチャがありませんでした。

![texture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105093/1ed84d1c-77f5-5d1d-b399-583c7c3eab12.png)

そこで自分でテクスチャを貼る方法を調べたのですがいまいち分からず、テクスチャありのライコウとスイクンの3Dモデル素材を探すことにしました。無事以下にありました。他にも3Dモデルの素材置き場は後述しています。

- [ライコウ](https://3dwarehouse.sketchup.com/model/u9ca17e58-5070-48dd-948a-947b3d42d4b4/Raikou-Pok%C3%A9mon-X-and-Y)
- [スイクン](https://3dwarehouse.sketchup.com/model/u476ce6de-1859-4598-9736-370255a91f36/Suicune-Pok%C3%A9mon-X-and-Y)

素材の読み込みは適宜変えてください。

```swift

//sceneとnodeを読み込み
guard let scene = SCNScene(named: "model.scn", inDirectory: "art.scnassets/Raikou") else {fatalError()}
guard let bearNode = scene.rootNode.childNode(withName: "SketchUp", recursively: true) else {fatalError()}
```

<img width="1444" alt="xcode.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105093/6cf39e42-0f56-ae81-4a35-9fd54c4122d4.png">


# 素材置き場
ポケモンの素材でいうと、以下4つでは確認できました。

- [Free3D](https://free3d.com/)
- [3D Warehouse](https://3dwarehouse.sketchup.com/)
- [Sketchfab](https://sketchfab.com/)
- [3dsky](https://3dsky.org/)

その他、人や家具など様々な3Dモデルが以下記事にまとまっているので、参考にしてみてください。

- （参考）[3Dモデルが無料,フリーでダウンロードできるサイト25選！CG素材](https://artjuku.com/3d-cg-free-model/)

# daeからscnの変換方法
Xcode上で変換できます。

<img width="782" alt="dae_to_scn.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105093/511056a9-9110-4d05-efd9-cc827ef19d44.png">




# rarファイルの解凍方法
素材の中には拡張子が `rar` という圧縮ファイルがあります。 `brew` で `unrar` をインストールして利用してください。

```
$ brew install unrar
$ unrar e hoge.rar
```


# 展望・感想
水平面を検知する度にライコウやスイクンを表示されてしまうので、1体だけ表示するために以下のコードを書き加えたが、ベストプラクティスはなんなのか。

```swift

class OnceExec {
    var isExec = false
    func call(onceExec: ()->()){
        if !isExec {
            onceExec()
            isExec = true
        }
    }
}
```
```swift

onceExec.call {
 // 1度だけ呼びたいコード
}
```

- （参考）[[Swift]viewWillAppearなどで一度だけ実行したい処理を書く (Swift3対応)](https://qiita.com/spelunker_muz/items/d6a8858cf6dd5da8b889)

複雑な構造のモデルの場合は `.scn` ではなく `.dae` から `SCNScene` を作った方が良いのか。

- （参考）[SceneKitで扱える3Dモデルのフォーマット／アニメーションつき3DモデルをSceneKitで使う](https://qiita.com/shu223/items/0161f82d000d5cdf009c)

スイクン縮尺ミスって小さくなっちゃったのはご愛嬌。

```swift

// Xmを基準にした縮尺を計算
let magnification = 0.5 / w
bearNode.scale = SCNVector3(magnification, magnification, magnification)
```