HoloLensで壁に落書きする方法

# 概要
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">スプレーで壁に落書きできるHoloLensアプリ<br>スプレーは気分<a href="https://twitter.com/hashtag/HoloLens?src=hash">#HoloLens</a> <a href="https://twitter.com/hashtag/HoloLensJP?src=hash">#HoloLensJP</a> <a href="https://t.co/ykL3CTT00u">pic.twitter.com/ykL3CTT00u</a></p>&mdash; アキヒロ (@akihiro01051) <a href="https://twitter.com/akihiro01051/status/885874103508271104">2017年7月14日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

- HoloLensで壁に落書きできるアプリを作ってみました
- HoloToolkitとInkPainterを組み合わせて簡単に実装できます
- エアダスターとAirTapを組み合わせると塗ってる感が出ます

# 仕組み
## 開発環境
- Windows10
- Unity5.6
- VisualStudio2015
- HoloToolkit-1.5.7.0(https://github.com/Microsoft/HoloToolkit-Unity/releases)
- InkPainter(https://www.assetstore.unity3d.com/jp/#!/content/86210)
- エアダスター(https://www.amazon.co.jp/gp/product/B005TH1HU6/ref=oh_aui_detailpage_o01_s01?ie=UTF8&psc=1)

## 仕組み
- HoloToolkitのSpatialMappingの機能一つ，SpatialProcessingを利用しています
- SpatialProcessingはSpatialMappingで得られたデータから平面構成のMappingデータに変換してくれるモジュールです
- 今回はSpatialProcessingで得られた平面にInkPainterを用いて落書きを行います

 
## 実装
1. シーンのロード
    - HoloToolkitをプロジェクトにインポート(この時HoloToolkit-Testsもインポートする)
    - InkPainterをインポート
    - HoloToolkit-Tests/SpatialMapping/Scenes/SpatialProcessing.unityをロード
   <img width="1920" alt="Paint1.png" src="https://qiita-image-store.s3.amazonaws.com/0/86283/ed8ad4f7-0658-b109-abed-3ae18a749e5b.png">

1. Inputモジュールの追加
    - HoloToolkit/Input/PrefabsからInputManagerとCursor/CursorをHierarchyに追加
  <img width="1920" alt="Paint2.png" src="https://qiita-image-store.s3.amazonaws.com/0/86283/ff608cf3-22a5-6daa-2a1f-859d26db0e06.png">


1. SurfacePlaneの変更
   HoloToolkit/SpatialMapping/Prefabs/SurfacePlaneを一部変更します．
 - スクリプトの追加
     - InspectorからInkCanvasを追加
 - Colliderの変更
     - BoxColliderをMeshColliderに変更する 
 - マテリアルの追加
     - SurfacePlaneにアタッチされているマテリアル(HoloToolkit_Default)のShaderをUnlit/Transparentに変更
     - Textureを以下の画像に変更(透明な画像です) 
![alphaImage.png](https://qiita-image-store.s3.amazonaws.com/0/86283/c5062c9e-f3a1-6027-6a3b-eb25aff9d6d2.png)

    ↑透明画像

 - コードの修正
     - SurfacePlane.csの126行目を削除        
``` 
SetPlaneMaterialByType();
```
 <img width="1918" alt="Paint3.png" src="https://qiita-image-store.s3.amazonaws.com/0/86283/44faa7e8-ad42-be42-9733-308a602253a9.png">


1. ペイント入力の実装
 - ペイント入力のコード(Paint.cs)を以下に示します
 - Paint.csをHoloLensCameraに追加しBrushTextureとBrushColorを設定
 - メニューバーのHoloToolkitからConfigure/ApplyHoloLensCapabilitySettingを選択しSpatialPerceptionを有効にする
 - BuildWindowよりプロジェクトをビルドしHoloLensで確認してください

 ```cs:Paint.cs
using UnityEngine;
using Es.InkPainter;
using UnityEngine.VR.WSA.Input;

public class Paint : MonoBehaviour {

    [SerializeField]
    private Brush brush;

    private bool pressflag = false;

    private void Start()
    {
        InteractionManager.SourceUpdated += InteractionManager_SourceUpdated;
        InteractionManager.SourcePressed += InteractionManager_SourcePressed;
        InteractionManager.SourceReleased += InteractionManager_SourceReleased;
    }

    private void Update()
    {

    }

    void InteractionManager_SourceUpdated(InteractionSourceState state)
    {
        if (pressflag == true)
        {
            Vector3 v;
            state.properties.location.TryGetPosition(out v);
            RaycastHit hitInfo;
            if (Physics.Raycast(v, Camera.main.transform.forward, out hitInfo))
            {
                var paintObject = hitInfo.transform.GetComponent<InkCanvas>();
                if (paintObject != null) paintObject.Paint(brush, hitInfo);
            }
        }

    }

    void InteractionManager_SourcePressed(InteractionSourceState state)
    {
        pressflag = true;
    }

    void InteractionManager_SourceReleased(InteractionSourceState state)
    {
        pressflag = false;
    }
}
 ```

<img width="1920" alt="Paint4.png" src="https://qiita-image-store.s3.amazonaws.com/0/86283/d3e1ec5d-283c-730b-bf5b-2bc4965c0f34.png">

HoloLensでアプリ起動後
- SpatialMappingによるワイヤーフレームの表示
- SpatialProcessing後に透明色に変更
- AirTapにより視線上の壁にペイントされます


# まとめ
- 壁にエアダスター向けながらAirTapして遊んでください
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">スプレーで壁に落書きできるHoloLensアプリ<br>スプレーは気分<a href="https://twitter.com/hashtag/HoloLens?src=hash">#HoloLens</a> <a href="https://twitter.com/hashtag/HoloLensJP?src=hash">#HoloLensJP</a> <a href="https://t.co/ykL3CTT00u">pic.twitter.com/ykL3CTT00u</a></p>&mdash; アキヒロ (@akihiro01051) <a href="https://twitter.com/akihiro01051/status/885874103508271104">2017年7月14日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

- もっとすごいのあるのでぜひこちらも見てください
    - http://qiita.com/arcsin16/items/9e2ab61bb62120f48f34