【Three.js】360°パノラマビューワーをスマホやタブレットのジャイロスコープで閲覧できるようにする

#<i class="fa fa-camera" style="font-size:1em;"></i> 概要



> 	- [【Three.js】360°パノラマビューワーを作ってグリグリ操作出来るようにした（スマホ対応）](http://qiita.com/kingpanda/items/1c3a47765b40d6d62f46)

という記事で、Three.jsを使ってシンプルな360°パノラマビューワーを作成しましたが、
スマホやタブレットで表示させた場合、PCと同じようにタッチでグリグリと視点を変えるようなものだったので、今回はジャイロスコープを使って、端末を傾けると画面が追従して視点を変えれるようにしたいと思います。

せっかく作ったので、上記の記事のコードをもとに修正していきます。

今回の修正で対応した項目は以下のとおりです。

> 	- ジャイロスコープ対応

コードは全て公開しますが、Three.jsの細かい部分の説明はしません。
最後にデモとGithubのリンクを用意してますので、そちらを参考にしてください。


#<i class="fa fa-camera" style="font-size:1em;"></i> Three.jsと必要なライブラリを読み込む


[Three.jsの公式サイト](http://threejs.org/)からダウンロードしたフォルダの中から以下の3つのファイルを使います。

> 	- Three.min.js
> 	- OrbitControls.js
> 	- **DeviceOrientationControls.js**　(NEW)

PCのマウスぐりぐり操作用に「OrbitControls.js」を使い、ジャイロ対応用「**DeviceOrientationControls.js**」を使います。

どちらのファイルも「/examples/js/controls」にあります。

これらと一緒に、メインのプログラムを書く「main.js」を作って、「index.html」で以下のように読み込みます。

```html:index.html
<div id="stage"></div>

<script src="three.min.js"></script>
//PC操作用
<script src="OrbitControls.js"></script>
//スマホジャイロ用
<script src="DeviceOrientationControls.js"></script>
//メイン
<script src="main.js"></script>
```

「OrbitControls.js」は、PCのマウスぐりぐり操作用に使いたいので、そのまま残しておきます。

#<i class="fa fa-camera" style="font-size:1em;"></i> メインのプログラム

「main.js」に以下のコードを書きました。
UAでスマホ・タブレット・PCの切り分けを行い、それぞれで操作の処理が違うようにしています。
重要なのは**control**の部分で、簡単に説明するとカメラの操作方法を変えているだけということになります。
**render()**でレンダリングする際にも、どちらのカメラ操作を使うか、回転アニメーションを使うかを分けています。
そして、render()内の毎回の描画部分で**update()**メソッドを呼びだします。


```js:main.js

(function(){

  var ua = navigator.userAgent;
    if (ua.indexOf('iPhone') > 0 || ua.indexOf('iPod') > 0 || ua.indexOf('Android') > 0) {
        var sp = true;
    }else if(ua.indexOf('iPad') > 0 || ua.indexOf('Android') > 0){
        var sp = true;
    }

  var width = window.innerWidth,
      height = window.innerHeight;

  //scene

  var scene = new THREE.Scene();

  //mesh

  var geometry = new THREE.SphereGeometry( 5, 60, 40 );
	geometry.scale( - 1, 1, 1 );

	var material = new THREE.MeshBasicMaterial( {
	   map: THREE.ImageUtils.loadTexture( 'test.jpg' )
	} );

	sphere = new THREE.Mesh( geometry, material );

	scene.add( sphere );

  //camera

  var camera = new THREE.PerspectiveCamera(75, width / height, 1, 1000);
  camera.position.set(0,0,0.1);
  camera.lookAt(sphere.position);

  //helper

  var axis = new THREE.AxisHelper(1000);
  axis.position.set(0,0,0);
  scene.add(axis);

  //render

  var renderer = new THREE.WebGLRenderer();
  renderer.setSize(width,height);
  renderer.setClearColor({color: 0x000000});
  document.getElementById('stage').appendChild(renderer.domElement);
  renderer.render(scene,camera);

  //control

  if(sp){
    var gcontrols = new THREE.DeviceOrientationControls(camera, renderer.domElement);
  }else{
    var controls = new THREE.OrbitControls(camera, renderer.domElement);
  }

  function render(){
    requestAnimationFrame(render);
    window.addEventListener( 'resize', onWindowResize, false );
    renderer.render(scene,camera);

    if(sp){
      gcontrols.connect();
      gcontrols.update();
    }else{
      sphere.rotation.y += 0.05 * Math.PI/180;
      controls.update();
    }
  }
  render();
  function onWindowResize() {
		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();
		renderer.setSize( window.innerWidth, window.innerHeight );
	}

})();

```

#<i class="fa fa-camera" style="font-size:1em;"></i> デモ

[DEMO](http://king-panda.github.io/gyro_panorama/)

サンプルの置き場はこちらです。
https://github.com/king-panda/gyro_panorama

#<i class="fa fa-camera" style="font-size:1em;"></i> 最後に

Three.js側で既に用意されているライブラリを使えば簡単にジャイロ対応を行うことができます。あとこれにプラスで、二眼にできるライブラリを併用すれば、Cardboard等のHMDでヴァーチャル体験させることもできるでしょう。