Vuforia + argon.js = ブラウザでAR

こちらは[OthloTech Advent Calendar 2017](https://qiita.com/advent-calendar/2017/othlotech)9日目の記事です。

[crssnky](https://twitter.com/crosssoniky28)です。

5年前くらいにARtoolkitで遊んでたのを思い出して、久しぶりにARやりたいなぁ。と思ってたところに、ブラウザでARができると知りました。
これならWindows使いのiPhone持ちという残念な僕の環境でもモバイルARアプリもどきが作れますね。
それならいっちょ試してみますか！っていう半年くらい前の掘り起こし。

# 試したこと
Vuforia + argon.js = ブラウザでAR
ターゲットの上に画像を重ねるAR

# 予備知識
-  AR(雰囲気で可)
-  three.js(雰囲気で可)
-  html + js(雰囲気で可)
-  英語 Vuforiaの設定で必要(Google翻訳でたぶん可)

# 材料
-  [Argon](https://www.argonjs.io/) : argon.jsというフレームワークとArgon4というブラウザの組み合わせ。  
カメラ映像をブラウザ上に載せる特殊なブラウザ。
-  [Vuforia](https://developer.vuforia.com) : ARプラットフォーム。   
[Unityと組み合わせる](https://unity3d.com/jp/partners/vuforia)と良い出汁が取れる。
-  重ねる画像
![test.png](https://qiita-image-store.s3.amazonaws.com/0/152708/b80ab67a-e622-626a-68ee-ff8904689c65.png)

# 作り方
### 1. おまじないを唱える
ARの設定となる、いわゆる"おまじない"要素が多いため、argon.jsの[Tutorial — Part 4: Reference Frames and Vuforia Tracking](https://docs.argonjs.io/tutorial/part4/)を動くようにしておくと"おまじない"が終わる。
(つまり、https://github.com/argonjs/docs/tree/gh-pages/code/4-vuforia)

### 2. 画像を読み込む
サンプルの46行目,47行目からは、three.jsで使える3Dテキストのフォントの読込およびエフェクトの追加、3Dテキストモデルの生成までを行っている。
今回は文字ではなく画像を出したいので、ここを変える。  

```javascript:
var loader = new THREE.TextureLoader();
loader.crossOrigin = "*";
loader.load(".png", function (tex) {
  var geometry = new THREE.PlaneGeometry(202.4, 101.2);
  mesh = new THREE.Mesh(geometry, new 
  THREE.MeshBasicMaterial({ map: tex }));
  argonTextObject.add(mesh);
  argonTextObject.scale.set(0.001, 0.001, 0.001);
});
```
まず、`FontLoader()`の代わりに`TextureLoader()`を宣言し、テクスチャを読み込めるようにする。
そして読み込んだら、画像を貼るための板3Dモデルを生成し、そこに読み込んだテクスチャを貼り付ける。
その後はARで操作したいオブジェクトをまとめた(今回は一個だけど)親オブジェクトである`argonTextObject`へ追加し、見えにくいくらい小さくしておく。
### 3. ARの動作
サンプルの108行目からは実際にARの動作を記述している。
`init()`の**encryptedLicenseData**はVuforiaのライセンスを暗号化したものを載せる。ちなみに、ドメインを限定する情報も付加できる。→https://docs.argonjs.io/start/vuforia-pgp-encryptor/
無事通過できたら、ARのターゲットが記述されたDatasetを読み込む。
> // the vuforia API is ready, so we can start using it.
// tell argon to download a vuforia dataset.  The .xml and .dat file must be together
// in the web directory, even though we just provide the .xml file url here 

Vuforiaでは、なんに使うにしてもARのターゲットに関する情報をまとめてDatasetとして登録して、それを使うという方法を取る。https://developer.vuforia.com/target-manager
それができたら、そのターゲット情報から一つ選んでカメラに映った時の動作を決める。それがサンプル129行目以降。updateEventなので、描画ループ毎に呼ばれる。
`gvuBrochurePose`はカメラから見たターゲットの位置、向き、状態である。これが`Argon.PoseStatus`と比べてどう一致するかを記述する。

-  KNOWN:追従可能の時ずっと
-  FOUND:追従可能になった瞬間
-  LOST:追従不可になった瞬間

**KNOWNの場合**
`gvuBrochureObject`というターゲットに常に追従する空オブジェクトの位置をターゲットの位置と合わせる。
**FOUNDの場合**
`gvuBrochureObject`へ追従させたいものをまとめたオブジェクト`argonTextObject`を追加し、`gvuBrochureObject`内でのLocalPositionを0にする。
**LOSTの場合**
`gvuBrochureObject`とは関係ないオブジェクト`userLocation`(ユーザー視点に追従)へ`argonTextObject`を追加し、視界外へ避難させる。

以上で完成です。
# 実際にやってみた
![2017-12-09 17.14.00.jpg](https://qiita-image-store.s3.amazonaws.com/0/152708/9f2cad2a-261f-c817-cfa4-014e6511b85c.jpeg)

![2017-12-09 17.14.18.png](https://qiita-image-store.s3.amazonaws.com/0/152708/ae66a735-011b-22a1-912d-6424d60c7e87.png)
上が普通のカメラで撮った写真。
下がそのままの位置を維持して、「SNICKERS」の文字に合わせて画像をARしているスクショ。(`THREE.PlaneGeometry(202.4, 101.2)`したので横長です。)

ARなんだから動いてないと意味ないだろ。というわけで、前にサンプルを動かした時の動画を置いておきます。物体の上でも綺麗に追従していますね。
[![Vuforia + argon.js](http://img.youtube.com/vi/4unGmBG92ag/0.jpg)](http://www.youtube.com/watch?v=4unGmBG92ag)

# 締め
以上で「Vuforia + argon.js = ブラウザでAR」を終わります。
半年前はiOSしか無かったArgon4も、今秋からAndroid版も配信され、マルチプラットフォームで気軽にブラウザARができる時代になりました。
これを機に冬休みは、ARで遊んでみるのも一興ではないでしょうか。
今回のやつ→https://github.com/crssnky/argonjsARsample