【HTC Vive】コントローラ２本でクロマキー合成をする方法

# 【HTC Vive】コントローラ２本でクロマキー合成をする方法

HTC Viveでクロマキー合成をするためにはカメラポジション算出の為コントローラがもう一本必要となります。
（合計３本のコントローラ）
アメリカではコントローラの単品販売が始まりましたが日本ではまだのようなので、クロマキー合成するにはHTC Viveをもう１セット購入する必要があります。

コントローラ２本でクロマキー合成をするための仮想空間内カメラ作成手順となります。

## ２本のコントローラでクロマキー合成をする原理
SteamVR内では３本目のコントローラにExternalCameraが割りあたってますので、仮想コントローラを作成してあたかも３本目のコントローラがあるかのように振る舞います。

## やり方

### 1. Virtual Controller Driverのダウンロード＆展開

http://secondreality.co.uk/MixedRealityTwoController-0-0-3.zip
ここからVirtual Controller Driverをダウンロードして展開します。

### 2. Virtual Controller Driverのセットアップ

展開すると中に【virtualcontroller】というフォルダーがありますので、フォルダーごとそのままSteamVRのドライバーが入ってるところにコピーします。

```
C:\Program Files (x86)\Steam\steamapps\common\SteamVR\drivers\
```
通常は上記のフォルダにドライバーがありますので、そのままコピーしてDLLは以下のパスに入ります。

```
C:\Program Files (x86)\Steam\steamapps\common\SteamVR\drivers\virtualcontroller\bin\win64\driver_virtualcontroller.dll
```

### 3. 【steamvr.vrsettings】を設定し【activateMultipleDrivers】をONにします

【steamvr.vrsettings】は通常は以下にあります。

```
C:\Program Files (x86)\Steam\config\steamvr.vrsettings
```

メモ帳か何かで開いて、最後に

```
"activateMultipleDrivers" : true
```
追加します。
（前の行の最後にカンマを忘れないこと、記述を間違えるとSteamVRが立ち上がらなくなります）

* サンプル

```json
{
   "camera" : {
      "enableCamera" : true
   },
   "steamvr" : {
      "background" : "C:\\Program Files (x86)\\Steam\\steamapps\\common\\SteamVR\\resources\\backgrounds\\viveNight.png",
      "mirrorViewGeometry" : "0 0 1080 600",
      "activateMultipleDrivers" : true
   }
}

```

### 3. Virtual Controller Driverを認識させる

設定に問題がなければこれで認識します。

1. 一度SteamVRを終了します
2. SteamVRが終了している状態で２本のコントローラの電源を入れます

![thirdController.png](https://qiita-image-store.s3.amazonaws.com/0/79067/63e2be37-9e94-8cb5-19a8-7e3eab1b7f99.png)

問題がなければ３本目のコントローラが出てきます。

### 4. 該当するUnityコンテンツのフォルダー内に【externalcamera.cfg】を作成して実行します

該当するUnityコンテンツのフォルダーに【externalcamera.cfg】を作成します
中身は下記のような感じです。

```
x=0
y=0
z=0
rx=0
ry=0
rz=0
fov=45
near=0.1
far=1000
```

【externalcamera.cfg】を作成後、Unityコンテンツを実行すると画面が４分割になり、左下が仮想空間内の仮想カメラとなります。

## カメラの位置合わせ
３本目のカメラの原点はベースステーション１が基準となってます。
先ほど展開したMixedRealityTwoController-0-0-3.zipに【cameraAlign.exe】というUnityコンテンツがあり、このコンテンツで仮想空間内で【externalcamera.cfg】を作成できます。

* グリップを握れば放射線状に伸びるカメラの座標系が表示
* セーブをクリックすると、動的に【externalcamera.cfg】が作成

作成された【externalcamera.cfg】を該当するUnityコンテンツに持っていき、リアルと仮想のカメラのポジションを合わせることができます。

## いちいち【externalcamera.cfg】を書き変えてコンテンツの再起動がめんどくさい

SteamVR_ExternalCamera.csを修正することで、動的にexternalcamera.cfgを読ませることが出来ます。
以下、ソース追加箇所です。

```csharp
using System.IO;
  ・
　・
　・

    bool configHasChanged = true;

    void Start()
    {
        var root = Directory.GetParent(Application.dataPath).FullName;
        FileSystemWatcher watcher = new FileSystemWatcher(root, "externalcamera.cfg");
        watcher.NotifyFilter = NotifyFilters.LastWrite;
        watcher.EnableRaisingEvents = true;
        watcher.Changed += (a, b) => { configHasChanged = true; };
    }
    void Update()
    {
        if (configHasChanged)
        {
            ReadConfig();
            cam.fieldOfView = config.fov;
            var offset = cam.transform;
            offset.localPosition = new Vector3(config.x, config.y, config.z);
            offset.localRotation = Quaternion.Euler(config.rx, config.ry, config.rz);
            configHasChanged = false;
        }
    }

```





---
参考
https://steamcommunity.com/app/358720/discussions/0/405694031549662100
http://secondreality.co.uk/blog/how-to-create-mixed-reality-videos-for-the-vive-with-two-controllers/