Looking Glass の Three.js が実装されたのでキャリブレーション結果方法を見てみた

# はじめに

*こんにちは、のんびりエンジニアのたっつーです。*
*[ブログ](https://www.fast-system.jp/)を運営しているのでよろしければ見てください。*

[LookingGlass Three.js](https://lookingglassfactory.com/downloads/three-js-library-looking-glass/) 実装が公開されたので中身を軽く読んでみました、私としてはキャリブレーション結果（個体情報） 取得 の部分がどういった実装になっているのか気になったための確認となります。

![threejs_opt.gif](https://qiita-image-store.s3.amazonaws.com/0/227880/4460e0ce-f83c-b8db-07d4-be30091e9468.gif)

# 経緯

以前、[Unity：Looking Glass を WebGL を使ってブラウザで表示する](https://www.fast-system.jp/unity%ef%bc%9alooking-glass-%e3%82%92-webgl-%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e3%81%a7%e8%a1%a8%e7%a4%ba%e3%81%99%e3%82%8b/)の記事を書いた際に、Looking Glass ではキャリブレーション結果（個体情報）をUSB経由で取得してその結果により表示の調整を行っています。

***Unity で WebGLで実装しても手元の環境でうまく表示されない原因はここのキャリブレーション結果（個体情報）がUSB経由で取得できないためにおこる原因となります。（ブラウザで動作する場合デバイスへのアクセスはセキュリティの制約があるので取得が難しい事に起因しています）***

なので、Three.js での実装が公開されると情報を聞いたのでこの実装をどう解決しているのか気になっていたためその調査結果となります。

# ソースコードを読んでみた結果

以下の部分が該当部分になります、doLoadEEPROM 関数になっており、ここでキャリブレーション結果（個体情報）を取得しています。

```C#
	function doLoadEEPROM (inInit)
	{
        var OSName="Unknown OS";
        if (navigator.appVersion.indexOf("Win")!=-1) OSName="Windows";
        if (navigator.appVersion.indexOf("Mac")!=-1) OSName="MacOS";
        if (navigator.appVersion.indexOf("X11")!=-1) OSName="UNIX";
        if (navigator.appVersion.indexOf("Linux")!=-1) OSName="Linux";
        
		var ws = new WebSocket('ws://localhost:11222/');
		var finished = function () {
			ws.close();
		};
		var timeout = setTimeout(function () { 
			var errstr = "Calibration not found in internal memory.";
            if (inInit) {
				console.log(errstr); 
			} else { 
				alert(errstr);
			}
			finished();
		}, 800);
		ws.onmessage = function(event) {
			console.log("New calibration loaded from internal memory.");
			saveCalibration(event.data);
			applyCalibration(event.data);
			clearTimeout(timeout);
            initialized = true;
			finished();
		};
		ws.onerror = function(event) {
			if (confirm("Three.js driver not detected! Click OK to download. If you have already installed the driver, please make sure port 11222 is open.")){
                if(OSName == "Windows"){
				    window.location.href = "https://s3.amazonaws.com/static-files.lookingglassfactory.com/WebCalibrationBridge/LKG_ThreeJsDriver_Win.exe";
                } else if(OSName == "MacOS"){
                    window.location.href = "https://s3.amazonaws.com/static-files.lookingglassfactory.com/WebCalibrationBridge/LKG_ThreeJsDriver_Mac.pkg"
                } else{
                    alert("Only Windows and OSX operating systems are currently supported for the Three.js library.")
                }
			}
			finished();
		};
	}
```

まずは、ローカルPCの 11222 ポートに対して WebSocket を開こうとします。

```C#
		var ws = new WebSocket('ws://localhost:11222/');
```

11222 ポートへの WebSocket オープンに失敗した場合、ドライバーがインストールされていないと判断してダウンロードしてインストールしようとします。

```C#
		ws.onerror = function(event) {
			if (confirm("Three.js driver not detected! Click OK to download. If you have already installed the driver, please make sure port 11222 is open.")){
                if(OSName == "Windows"){
				    window.location.href = "https://s3.amazonaws.com/static-files.lookingglassfactory.com/WebCalibrationBridge/LKG_ThreeJsDriver_Win.exe";
                } else if(OSName == "MacOS"){
                    window.location.href = "https://s3.amazonaws.com/static-files.lookingglassfactory.com/WebCalibrationBridge/LKG_ThreeJsDriver_Mac.pkg"
                } else{
                    alert("Only Windows and OSX operating systems are currently supported for the Three.js library.")
                }
			}
			finished();
		};
```

11222 ポートへのWebSocketオープンに成功した場合、キャリブレーション結果（個体情報）を取得して正常に描画処理への調整パラメータとして設定します。

```C#
		ws.onmessage = function(event) {
			console.log("New calibration loaded from internal memory.");
			saveCalibration(event.data);
			applyCalibration(event.data);
			clearTimeout(timeout);
            initialized = true;
			finished();
		};
```

# 結果

簡単でしたね、キャリブレーション結果（個体情報）を取得する方法としてどういったアプローチをするのかと思っていたのですが、予想通りバックグラウンドにプロセスを立ち上げて、WebSocket 経由で情報を取得する形になっていました。

Looking Glass の特性上、出荷時に個体毎にキャリブレーションを行いその値を本体に保存しているのでこのような手法に落ち着くのは仕方がない事かと思われます。

***よい、Looking Glassライフを！***

# 元記事

*よければ ブログ「[初心者向けUnity情報サイト](https://www.fast-system.jp/)」の方にも色々記載しているのでぜひご参照いただければと思います。*

- [Looking Glass の Three.js が実装されたのでキャリブレーション結果方法を見てみた](https://www.fast-system.jp/looking-glass-%e3%81%ae-three-js-%e3%81%8c%e5%ae%9f%e8%a3%85%e3%81%95%e3%82%8c%e3%81%9f%e3%81%ae%e3%81%a7%e3%82%ad%e3%83%a3%e3%83%aa%e3%83%96%e3%83%ac%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e7%b5%90/)
- [Unity：Looking Glass を WebGL を使ってブラウザで表示する](https://www.fast-system.jp/unity%ef%bc%9alooking-glass-%e3%82%92-webgl-%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%83%96%e3%83%a9%e3%82%a6%e3%82%b6%e3%81%a7%e8%a1%a8%e7%a4%ba%e3%81%99%e3%82%8b/)