AR.jsを使って恐竜を家に呼んでみた

# はじめに
こんにちは！今回初参加させていただきます。
[CYBIRD Advent Calendar 2022](https://qiita.com/advent-calendar/2022/cybird)、9日目担当の@ayany0_zzZです！:hugging:
前回は@moffunnyaさんの「Terraformを使った環境構築入門（AWS）」でした。

初めての投稿なので、お手柔らかにお願いいたします…！

# 自己紹介
私は、2022年にサイバードに新卒入社いたしました。
ドキドキワクワクの研修期間を経て、現在は:rose:[イケメン王子~美女と野獣の最後の恋~](https://ikemen.cybird.ne.jp/title/prince/original/):rose:のクライアント兼サーバーエンジニアとして開発に携わらせていただいております！
ちいかわとポケモンとゲームが大好きなひよっこエンジニアです:hatching_chick::dizzy:

最近ではポケモン最新作「ポケットモンスターバイオレット」で、色違い集めに励んでいます。
目標は、<font color="LightSkyBlue">__1BOXを色パチリスで埋めること__</font> です！　
どうぞ、よろしくお願いいたします！:pray_tone1:

# 概要
ポケモンSVに影響されて、__<font color="OrangeRed">"現実世界にはもう存在しない何か"</font>__ を現実世界に召喚したいと思ってしまいました。

ですので今回は、~~コライドn~~ 恐竜の皆様を
「<font color="OrangeRed">__AR.js__</font>」で
現実世界（私の家）に召喚したいと思います！:sparkles:

## 開発環境
macOS Monterey（バージョン12.1）
Apple M1 Proチップ搭載

## 必要なもの
- Blender
- phpが使えるWebServer

## ドキュメントルートのフォルダ構成
- Index.html
- AR.php
- glbフォルダ（3Dモデルを入れるフォルダ）
    - XXX.glb
- Imagesフォルダ
    - XXX.jpeg
- pattern-marker.png
- pattern-marker.patt

`Index.html`で召喚したい恐竜の画像を表示し、選択後に`AR.php`が呼ばれてARのメイン処理が走るイメージです。

# 個体準備編
今回は、みんな大好き<font color="OrangeRed">__ティラノサウルス__</font>くんを用意したいと思います。

### 3Dモデルの用意
立体的な子を呼び出したいので3Dモデルでの実装をしたいのですが…
モデリングができないので、以下の無料アセットを使用させていただきました:pray_tone1:

https://www.turbosquid.com/ja/3d-models/t-rex-fbx-free/933905#

拡張子をglbにしたいので、Blenderを使用して変換していきます。

### Blenderで諸々調整
Blenderを開いて、元々置いてあるキューブを削除。
`ファイル`→`インポート`→`FBX(.fbx)`で先程ダウンロードしたfbx形式のティラノさんをインポートします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/e1019dee-fcfe-34ee-1c23-9667d28483af.png)
<font color="Gainsboro">__クリック__</font>:zap:
![スクリーンショット 2022-12-08 15.29.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/793ea8bd-3629-6b2c-1bef-d44eeea47ef0.png)

わ〜！！出てきた！なんか消しゴムみたいで可愛いですね！:raised_hands_tone1:
色がついていないので、`3Dビューのシェーディング`（枠内のボタン）を右から2番目の`マテリアルプレビューモード`に変更します。
![ティラノ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/0be424a8-38f1-33f5-d12e-335facdcc4c4.png)
<font color="Gainsboro">__クリック__</font>:zap:
![スクリーンショット 2022-12-08 15.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/d137947c-0463-5c57-e684-bf84a8e2e2fb.png)
テクスチャが反映されると恐竜さが増しますねえ…！
ちなみに、ティラノサウルスさんは声帯がなくて吠えることはないみたいです。

…ジュラシックパークを見たくなってきたところで、しっかりと保存します。
`ファイル`→`エクスポート`→`gTF2.0(.glb/gltf)`でglb形式で保存し、glbフォルダに格納！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/8592b6bd-de4b-8cf9-1fb5-85a8ee6522f1.png)

個体の用意が完了しました〜！

***
#### おまけ
【Blenderでjpeg画像を作成する方法】
1. まず、カメラを選択します。
![スクリーンショット 2022-12-08 15.49.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/b7bc3eb9-8fda-6b59-0cf2-46b7f994eff2.png)

2. 左部のツールを使って、画像のように撮影したいオブジェクトを四角の中に収めます。
![スクリーンショット 2022-12-08 17.09.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/a504b250-2b97-9805-fd48-ea87617f1f84.png)

3. 枠内をクリックして、カメラビューに切り替えます。
![写真３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/559fd7ac-f9ea-77bc-652e-ed86c7d3d349.png)
<font color="Gainsboro">__クリック__</font>:zap:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/459e45b9-ec2a-d290-3fb5-52ceb78c1e1b.png)

4. `レンダー`→`画像をレンダリング`で、Blenderレンダーを開きます。
![スクリーンショット 2022-12-08 17.29.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/fc6f167a-9cb2-12bf-fea5-6309cf6ccafc.png)
<font color="Gainsboro">__クリック__</font>:zap:
![スクリーンショット 2022-12-08 17.30.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/02ac1343-7866-962e-2646-f2ff1f3785e4.png)

5. `画像`→`名前を保存`で開かれたウィンドウに、ファイル名を入力して保存します。
このとき、jepg形式でimagesフォルダに格納しました。
![スクリーンショット 2022-12-08 17.30.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/11dea376-b44c-b991-6dae-8a2a41fb1323.png)

できた画像がこちら！
![t_rex.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/71d659fb-3e92-f7ea-29af-02c051b163ee.jpeg)

迫力置いてきちゃった…。:cry:


# 召喚編
ここからスクリプトを書くなどします！
後少しで __<font color="OrangeRed">"現実世界にはもう存在しないティラノサウルス"</font>__ がお家に…！ワクワク:relaxed:
それではスタート！

### Webサーバーの準備
AR.jsはWebでARを実装できるソフトウェアなので、まずは実装するための環境を整えます。
今回はApacheを使用してサーバーを準備しました！

今まではWeb Server for ChromeでWebサーバーを立てていたのですが、phpに対応していませんでした:cry:
本当はHTMLだけでも実装できるみたいなのですが、なぜphpにこだわるかというと「今後同じページから違う3Dモデルも表示できたらいいな〜」と思ったからです。
__初めてのApache、macOSに標準搭載されているなら安心だよね！私にもできるよね！:dash:__


httpd.confを編集してドキュメントルートを設定後、以下の起動コマンドをターミナルで打ってみました。
```
$ sudo apachectl start
```
結果…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/d4ec43f2-8890-e44b-f8cc-1def28ec1351.png)
おっ、表示されました。ヤッター！:raised_hands_tone1:
じゃあ次はphpが本当に動くのか、確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/a33d96f0-7318-bf3a-0b00-c32d69b51f96.png)

__…え？なんで…？__

調べた結果、以下のようなことがわかりました。

:::note warn
macOS　Monterey以降はphpがバンドルされなくなった関係で、Homebrewを使って<font color="Red">phpを別途インストールする</font>必要がある
:::
:::note warn
macOS標準のApacheは、Homebrewでインストールしたphpを受け付けない為、Homebrewを使って<font color="Red">httpdを別途インストールする</font>必要がある
:::

えぇ…そんなことある…？:sob:

Homebrewはインストールしてあったので、上記2点のインストールと諸々の設定をして無事にphpを使用できるようになりました。
この記事ではその経緯は割愛させていただきますが、割と苦労したので後日備忘録として投稿できたらなと思います…。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/a55b7955-ae30-aef0-7e5a-039ea2dc0b94.png)
この画面が表示されたらOKです。

### マーカーの作成
次は、ARを認識させるための画像ファイルとpattファイルを作成します。

https://jeromeetienne.github.io/AR.js/three.js/examples/marker-training/examples/generator.html


こちらのサイトの`DOWNLOAD MARKER`をクリックしたら、pattファイルが簡単にダウンロードできました:raised_hands_tone1:
![あああああ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/b19507e7-c16b-172f-7933-3841d3decf55.png)

同じように`DOWNLOAD IMAGE`をクリックして、画像ファイルもダウンロードします。
![あああああ2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/1774e262-2bbe-0877-2a08-ef8678974e00.png)

上記2つをドキュメントルートのフォルダに格納して完了です。
私はデフォルトのマーカーを作成しましたが、オリジナルのマーカーを作成することもできるみたいです！すごい！！

あっ、ここで画像ファイルを印刷しておくといいと思います:ok_hand_tone1:

### プログラミング
まずは、`Index.html`からやっていきます:muscle_tone1:
```Index.html
<html>
    <head>
    	<meta charset="utf-8">
    	<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
    	<title>AR</title>
    </head>
    <body bgcolor="#464646">
    	<div style="float:left; margin:2px;"><a href="ar.php?id=0"><img src="images/t_rex.jpg" /></a></div>
    </body>
</html>
```

やっていることとしては、主に以下です。

:::note
ティラノサウルスの画像を表示
└画像を表示するために、予めそれぞれの画像を`images`フォルダに格納
:::

:::note
__画像をクリックしたらARで表示できる__ ようにしたいので、`ar.php`を呼び出せるようにリンクの埋め込み
:::


画面はこのような感じになっています。
ぽつんとティラノになってしまいましたね！:full_moon_with_face:
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/a2a8327b-477a-daea-8c42-d7e54072450a.png)
次に、`AR.php`でメイン処理を書いていきます。
```AR.php
<?php
	$glb_list[]=array("path" => "glb/t_rex.glb", "rotation" => "0 0 0", "scale" => "30.0 30.0 30.0");

	$id=0;
	// [ user.php ]
  	if(isset($_GET['id'])) {
		$id = $_GET['id'];
	}

	$glb_path=$glb_list[$id]["path"];
    $glb_rotation=$glb_list[$id]["rotation"];
	$glb_scale=$glb_list[$id]["scale"];
?>

<html>
	<head>
		<meta charset="utf-8">
      	<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no">
      	<title>AR</title>

		<!-- A-Frame ライブラリの読み込み -->
  		<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
  		<!-- AR.js ライブラリの読み込み -->
  		<script src="https://raw.githack.com/AR-js-org/AR.js/master/aframe/build/aframe-ar.js"></script>
    </head>
    <body>
		<div>
		<a-scene embedded arjs="debugUIEnabled:false; sourceType: webcam;" vr-mode-ui="enabled: false;" renderer="gammaOutput:true;" >
   			<a-assets>
   				<a-asset-item id="poke" src="<?php echo $glb_path ?>"></a-asset-item>             
   			</a-assets>
            <!-- a-markerのtypeにpatternを設定, 作ったpattファイルのパス指定 -->
      		<a-marker preset='custom' type='pattern' url="pattern-marker.patt">                            
   	    		<a-entity gltf-model="#poke" position="0 0 0" rotation="<?php echo $glb_rotation ?>" scale="<?php echo $glb_scale ?>" ></a-entity>
   	    	</a-marker>
   	    <a-entity camera></a-entity>
		</a-scene>
		</div>
	</body>
</html>
```
うーん長い！！！！:sweat_drops:
やっていることとしては、主に以下です。

:::note
idと表示したい3Dモデルの紐付け
└今後種類が増えるかもしれないので、配列で管理
:::

:::note
A -FrameライブラリとAR.jsライブラリの読み込み
:::

:::note
カメラの起動
:::

:::note
ARマーカーの設定
:::

:::note
3Dモデルの表示調整（大きさ、ライティング等）
:::

これで、召喚の準備は整いました。

## いざ召喚
私のスマホからティラノサウルスくん登場！
プリンターのインクがなくて、ARマーカーを印刷できなかったのでスマートフォンで表示させてみました。
![スクリーンショット 2022-12-08 18.15.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3020541/1dbfe34f-a7e2-6a28-d68b-f4ec9120165e.png)
小さいとちょっと可愛いかも…？:flushed:


# おわりに
最後まで本記事を読んでいただき、ありがとうございました！
拙い文で大変恐縮ですが、少しでも読んでて楽しい気持ちになっていただけていたら嬉しいです。:relaxed::sweat_drops:
動きのあるARも作れるみたいなので、ぜひ次元の離れた存在を私たちの世界に呼んでみてください！

[CYBIRD Advent Calendar 2022](https://qiita.com/advent-calendar/2022/cybird) 10日目は、@kyukkyu81さんの「クリスマスの夜に向けて密かに歌を練習するアレクサ」です。
アレクサも歌、好きなんですかね〜？タイトルからもう面白いので是非読んでみてください！