elm-3d-scene入門

# elm-3d-sceneとは
[elm-3d-scene](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-scene/latest/)は、Elmで手軽に3DCGを描画できるライブラリです。ゲーム作成にも使えますが、物理演算や衝突判定などの機能[^1]はなく、描画機能だけを持っています。
![capture1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/fefab162-e396-3f13-d6f1-fd35bca55d73.gif)
こんな感じのCGを作ることもできます。

# 早速いじってみましょう！
[elm-3d-scene](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-scene/latest/)の**Getting started**に記載されている通り、まずは[tutorial](https://github.com/ianmackenzie/elm-3d-scene/blob/master/TUTORIAL.md)を読むと雰囲気が掴めると思います。[examples](https://github.com/ianmackenzie/elm-3d-scene/blob/master/examples/README.md)には難易度別にサンプルプログラムが用意されており、それぞれellieでも動かせるようになっていますので、気軽にいじってみることができます。各サンプルプログラム内のコメントには、そのプログラムで解説したいポイントが書かれており、理解を助けてくれます。
![スクリーンショット 2020-12-03 3.12.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/a9b8a102-4fab-5f78-64ae-02ef15bc8d35.png)

# elm-3d-sceneの基本
[tutorial](https://github.com/ianmackenzie/elm-3d-scene/blob/master/TUTORIAL.md)を読むとわかりますが、**entity**と呼ばれるモノと**camera**を用意して**レンダリング**する。基本的にはこれだけです。
![entityandcamera.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/99c8f96f-1104-5a26-d2fa-2eff27f47f3b.png)
entityを作る際には、elm-3d-sceneで用意されているブロックみたいなものや球みたいなものを取り扱うこともできますが、Meshと呼ばれる三角形の集合体で立体を表現することもできます。ただし難易度が上がるようなのでこの記事では取り扱いません。elm-3d-sceneの背景にある[webglのドキュメント](https://package.elm-lang.org/packages/elm-explorations/webgl/latest/)にMeshに関する説明があります。

# つまずきやすい点

### 座標系
[elm-3d-sceneのパッケージドキュメント](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-scene/latest/)を読んでいると、よく3つの値を引数に取ることがあります。3D空間上の座標X・Y・Zです。これらの値が大きくなるとどちらの方向に進んで行くのかがドキュメントには明記されていないようでしたが、実際に試してみたところ以下のようになっていました。
![xyz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/1212cc7f-5569-7239-ffaf-dd882908492f.png)

### パッケージドキュメントの読み方

#### 型の探し方
elm-3d-sceneは他のライブラリを使用しています。そのためか、[elm-3d-sceneのパッケージドキュメント](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-scene/latest/)を読むとelm-3d-sceneで定義されていない型がいきなり登場します。使用しているライブラリは[tutorial](https://github.com/ianmackenzie/elm-3d-scene/blob/master/TUTORIAL.md)の冒頭に書いてありますので、[elm-3d-sceneのパッケージドキュメント](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-scene/latest/)を検索しても見つからない場合は、これらのドキュメントも探してみてください。

##### 例： [point関数](https://package.elm-lang.org/packages/ianmackenzie/elm-3d-scene/latest/Scene3d#point)
![スクリーンショット 2020-12-03 4.40.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/e70ffd2d-6e54-1719-8141-d7e73a54b4c8.png)
Quantityってなに！？Plainってなに！？と混乱しました…

![スクリーンショット 2020-12-03 4.43.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/dd6206c8-0b42-55c0-d57c-195cdd8ef34e.png)
Quantityは[elm-units](https://package.elm-lang.org/packages/ianmackenzie/elm-units/latest/)に。Plainはelm-3d-sceneの中にありました。但しelm-3d-sceneのメインモジュールであるScene3dではなく別のモジュールに含まれていました。

#### 関数の探し方
elm-3d-sceneの関数に必要な引数は大体何かの関数の結果なのですが、慣れるまではちょうど良い関数を見つけるのに苦労するかもしれません。期待している型を返す関数がなさそうに見えても、型エイリアスが定義されている場合が多いので探してみてください。

![スクリーンショット 2020-12-03 4.55.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/80d554f6-a272-c9a4-f646-45ce90769eaa.png)
Plainを返す関数が見つからなかったのですが、型エイリアスを見たらちょうど良い関数を見つけることができました。

# 参考：Elm Game Jam #5
Elmでゲームを作るイベント[Elm Game Jam #5](https://itch.io/jam/elm-game-jam-5)があります。今回のテーマは3Dです。[3Dゲーム作りの参考になる情報](https://dev.to/lucamug/3d-graphics-in-the-browser-with-elm-4oh3)もまとまっていますので、気軽に参加してみてはいかがでしょうか。
![スクリーンショット 2020-12-03 4.59.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/118890/61c31e79-72bd-6ec2-a7f1-7fdd6740f34b.png)

[^1]: 物理演算や衝突判定をしたい場合は、[elm-physics](https://package.elm-lang.org/packages/w0rm/elm-physics/latest/)を組み合わせて使うことができるようです。これについては、[はーなーさんの記事](https://superhahnah.com/try-wip-elm-3d-scene-vol2/)が参考になります。