Three.js の JSONLoader のメモ

# はじめに
Three.js には、いくつかのローダが添付されています。
その中の JSONLoader は JSON 形式のモデルデータをロードできるようです。

試した時のことをメモしておきます。

# Blender で JSON 形式のデータを作る
JSON 形式のデータは、テキストエディタでも作成できると思いますが、モデリングソフトで作成するのが一般的なようです。(そりゃ、そうですが)

ここでは、Blender を使います。

## Blender 用エクスポータ
Three.js には Blender 用のエキスポータが添付されています。
Blender で Three.js 用 JSON形式データをエクスポートできるようにするには、このエクスポータを Blender にアドオンとして追加します。

具体的には、Three.js のアーカイブ(2014.12.06時点の最新 r69)に含まれる　io_mesh_threejs ディレクトリを Blender アドオン配置用のディレクトリにコピーします。

    mrdoob-three.js-ca14c79/
     ├── :
     └── utils/
     　　　├── exporters/
     　　　│   ├── blender/
     　　　│   │   └── README.md    # 説明が書かれている
     　　　│   │   └── 2.65/
     　　　│   │       └── scripts/
     　　　│   │           └── addons/
     　　　│   │               └── io_mesh_threejs/  # <-- ディレクトリごとコピー

Ubuntu Linux 14.04 (Blender バージョンは 2.69) の場合ですが、Blender アドオン配置用ディレクトリは、

- ~/.config/blender/2.69/scripts/addons/
- /usr/share/blender/scripts/addons/

のいずれかのようです。(/usr/〜 の方は、README.md の記述と少し異なります)

私は /usr/〜の方にインストールしました。

    $ cd mrdoob-three.js-ca14c79/utils/exporters/
    $ cd blender/2.65/scripts/addons/
    $ sudo cp -r io_mesh_threejs /usr/share/blender/scripts/addons/

---
(※2015.02.07追記)
上記の方法の場合、コピー先の所有者ユーザ/グループは root/root になります。
Blender を一般ユーザで使用する場合、コピー先のアドインのファイルに読み取り権などのパーミッションが必要です。
今回は問題ありませんでしたが、zip など のアーカイブで配布されているアドインを上記の方法でインストールした場合、パーミッションが付与されない場合があります。(その場合、下記のように Blender のメニューで見ても該当アドインが表示されません)
アドオンの一般ユーザへのパーミッションが付与されていない場合、以下のような方法で対処します。

    $ cd /usr/share/blender/scripts/addons/
    $ sudo find io_mesh_threejs -exec chmod a+r {} \;  # ファイル(ディレクトリ含む)に読み取り権を付与
    $ sudo find io_mesh_threejs -type d -exec chmod a+x {} \;  # ディレクトリに実行権を付与
    $ cd -
 
---
エクスポータをインストールしたら、Blender を起動してそれを有効化します。
具体的には、Blender の「File-> User Preferences」の「Addons」タブの「Import-Export: three.js format」にチェックを入れます。

![blender-preferences1.png](https://qiita-image-store.s3.amazonaws.com/0/60624/8d820c93-8ac5-2e54-6846-88d3613d7bc6.png)

## モデルデータを作る
Blender でモデルデータを作ります。
といっても、私はモデリングできないので、デフォルトで作られる立方体をそのままエクスポートしました。
「File -> Export」で「Three.js (json)」を選択してエクスポートします。
ここではファイルの名前は 'cube.json' にしました。

# HTML の用意
以下のような HTML にしました。(Haml で記述してます)
three.min.js と TrackballControls.js は Three.js のアーカイブに含まれます。
環境に合わせて配置してください。

```haml:sample.haml
!!!
%meta(charset="UTF-8")
%title JSONLoader (Three.js)

%h1 JSONLoader (Three.js)
#stage

%script(src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js")
%script(src="build/three.min.js")
%script(src="js/controls/TrackballControls.js")

%script(src="myscript.js")
```
# スクリプトの用意
JSONLoader の使い方は以下のような感じです。
load() の第一引数にはモデルデータの URI を指定します。
第二引数にハンドラとなる関数を指定します。

```js
var loader = new THREE.JSONLoader();
loader.load(uri, function(geometry, materials) {
   var geo = geometry;
   var mat = new THREE.MeshFaceMaterial(materials);
   var mesh = new THREE.Mesh(geo, mat);
      :
}
```

ここでは以下のようにしました。(CoffeeScript で記述しています)
視点はマウスでぐりぐり変えられるようにしています。

```coffeescript:myscript.coffee
$ ->
  radians = (degree) -> degree * Math.PI / 180

  width = 500
  height = 300

  # scene
  scene = new THREE.Scene()

  # mesh
  new THREE.JSONLoader()
    .load 'cube.json', (geometry, materials) ->
              geo = geometry
              mat = new THREE.MeshFaceMaterial materials

              mesh = new THREE.Mesh geo, mat
              mesh.castShadow = true  # shadow
              mesh.scale.set 100, 100, 100
              scene.add mesh

  # mesh (plane)
  geo = new THREE.PlaneGeometry 500, 500
  mat = new THREE.MeshLambertMaterial
                    color : 0x0096d6
                    side : THREE.DoubleSide

  plane = new THREE.Mesh geo, mat
  plane.receiveShadow = true  # shadow
  plane.position.set 0, -150, 0
  plane.rotation.x = radians 90
  scene.add plane

  # axis helper
  scene.add new THREE.AxisHelper 1000

  # light
  light = new THREE.DirectionalLight 0xffffff, 1
  light.castShadow = true # shadow
  light.position.set 0,100,30
  scene.add light

  # ambient light
  scene.add new THREE.AmbientLight 0x550000

  # camera
  camera = new THREE.PerspectiveCamera 45, width / height, 1, 1000
  camera.position.set 200,300,500

  # controls (trackball control)
  controls = new THREE.TrackballControls camera

  # renderer
  renderer = new THREE.WebGLRenderer()
  renderer.shadowMapEnabled = true  # shadow
  renderer.setSize width, height
  renderer.setClearColor 0xeeeeee, 1
  $('#stage').append renderer.domElement

  # rendering
  animate = () ->
    requestAnimationFrame animate
    renderer.render scene, camera
    controls.update()

  animate()
```

Haml と CoffeeScript のソースを変換して、ローカル Web サーバに配置します。

    $ haml -q sample.haml sample.html
    $ coffee -c myscript.coffee


# 表示結果
モデリングが適当なので、質感の変な箱が表示されています。

![browse.png](https://qiita-image-store.s3.amazonaws.com/0/60624/c4fdb5e7-a921-a4cb-bfd1-7716c91330cc.png)

※ブラウザ: バージョン 39.0.2171.65 Ubuntu 14.04 (64-bit)

# 付記 (Ubuntu 用 メモ)
Ubuntu Linux 14.04 環境の話です。
Blender は以下のようにインストールしました。

    $ sudo apt-get install blender

また、README.md などの Markdown ファイルを端末で見る場合は以下のようにします。

    $ markdown README.md | w3m -T text/html

Markdown、w3m はそれぞれ以下のようにインストールしました。

    $ sudo apt-get install markdown
    $ sudo apt-get install w3m