HoloLensのSpatialMappingデータをブラウザで表示する

こんにちわ。HoloLensチームの佐藤です。
今回はアドベントカレンダーの記事ということで、日頃やらないようなお試し的なことをやってみようかとおもいました。
HoloLensは空間情報(Spatial Mapping)を取得する機能が端末に備わっております。
そしてこの空間情報のデータは、HoloLensのDevicePortalからダウンロードすることができます。
このデータは.objという形式なのですが、そもそも.objとは何なのかいう方はwikipedia に詳しく乗っているのでそちらを参照いただければと思います。(ちなみに私もそこで学びました)
以前からこのデータをHoloLens上だけでなく、自分が作ったwebアプリに表示して活用できないかを考えていまして、
調べていくとThree.jsが.obj形式の表示にも対応していることが判明し、今回はThree.jsを使ってブラウザに表示するところまでをやってみようと思います。

 

 

exmaplesページに様々なサンプルがあるのですが、どれもブラウザで実現しているとは思えないものばかりです。
(後々調べてみると、HoloLensのDevicePortalで表示している空間データもThree.jsで表示しているみたいです)
なお、ブラウザで3Dを表示する技術はWebGLという標準仕様があり、上記のThree.jsはWebGLを簡単に利用できるようにラップしたライブラリとなっています。
(全てのブラウザで利用できるわけではなく、互換性のあるものに限られます)
さっそく作業を進めていきます。

 

1. HoloLensから空間情報をダウンロードする
HoloLens Device PortalのViews->3D Viewの【Save】ボタンを押してローカルに保存します。
Views>3D Viewで見た空間情報
保存した.obj形式のファイルは。Windows10にインストールされている3D ビューアーアプリで閲覧することができます。
ちなみに弊社オフィスと廊下の一部をHoloLensで撮ったものです
2. Three.jsの環境を構築する
環境の構築はいろいろと方法あると思いますが、私は下記のやり方で環境構築いたしました。
私の使っている環境について
– OS : windows 10
– エディタ:Visual Studio Code
– ブラウザ:Microsoft Edge
Three.jsはここからダウンロードします。npmでインストトールすることができますが、今回はダウンロードしたもの(r99)を使ってみます。

 

3. とにかく表示してみる(実装)
では、下記のようなhtmlを用意します。
<!DOCTYPE html>
<html>
    <head>
    <meta charset="UTF-8" />
    <!-- three.js -->
    <script src="three.min.js"></script>
    <script src="loader/OBJLoader.js"></script>
    <script src="controls/OrbitControls.js"></script>

    <script src="main.js"></script>
    </head>
    <body>
        <canvas id="obj_canvas"></canvas>
    </body>
</html>


そして同一パスに下記のjsファイルを用意します。
window.addEventListener('DOMContentLoaded', init);
 
function init() {
 
    var width = 900;   //描画領域の幅
    var height = 600; //描画領域の高さ

    // Renderer作成
    const renderer = new THREE.WebGLRenderer({
      canvas: document.querySelector('#obj_canvas'), antialias: true
    });
    renderer.setClearColor( 0x222222 ); //backgroundcolor
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(width, height);
  
    // Scene作成
    const scene = new THREE.Scene();
  
    // Camera作成
    const camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000);
    camera.position.set(0, 0, 1000);
  
    // OBJのloader初期化
    var loader = new THREE.OBJLoader();

    loader.load(
      'assets/SpatialMapping.obj', // resource URL
      function ( object ) {

        objmodel = object.clone();
        objmodel.scale.set(20, 20, 20); //スケールの調整(そのままだと小粒表示)   
        objmodel.rotation.set(0, 0, 0);    
        objmodel.position.set(0, 0, 0);
 
        obj = new THREE.Object3D();
        obj.add(objmodel);
 
        scene.add(obj);                         
      },
      function ( xhr ) {
        console.log( ( xhr.loaded / xhr.total * 100 ) + '% loaded' );
      },
      function ( error ) {
        console.log( 'An error happened' );
      }
    );

    //light 作成
    const light = new THREE.DirectionalLight(0xFFFFFF);
    light.intensity = 3;
    light.position.set(1, 1, 1);
    scene.add(light);
  
    // コントロール生成
    controls = new THREE.OrbitControls(camera);
    controls.maxDistance = 5000.0;

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

    // 描画
    render();
  
    function render() {
      requestAnimationFrame(render);
    
      // レンダリング
      renderer.render(scene, camera);
    }
}

 

 

ブラウザで実行する前に注意点として、.objファイルをブラウザで表示するためにはプロトコルをhttpsやhttpにする必要があります。
ローカルで実行する場合、PCのIISを有効かし、MIMEタイプに.objファイルを追加する必要があります。
では実行してみます。

ここまでは簡単に表示することができました。
HoloLensのアプリで取得した空間情報をサーバーにアップロードして利用するようなシナリオがあったら表示用に利用できそうです。
それではまた。