MRが楽しい

MRやVRについて学習したことを書き残す

公式チュートリアル「HOLOGRAMS 210 2章」を試してみる

本日はチュートリアルお試し枠です。
いつも通り、以下ブログの記事を参考に実施します。
・HOLOLENS 公式チュートリアル HOLOGRAMS 210 GAZE 2章
 https://azure-recipe.kc-cloud.jp/2016/12/holograms-210-2/

参考記事にある通りにチュートリアルを実施します。
アプリをビルドすると、宇宙飛行士アプリにカーソルが出現するようになりました。
f:id:bluebirdofoz:20170517004644j:plain
カーソルは宇宙飛行士に当たっている間は青色のカーソルです。
f:id:bluebirdofoz:20170517004655j:plain
その他を見ると、白色のカーソルに変化します。
f:id:bluebirdofoz:20170517004659j:plain
更に見ている箇所のオブジェクトが白色に発行しています。
(上記画面だと右足が白くなっているのが分かります)


今回の新しい技術ポイントは特定オブジェクトを見るとカーソルの色が変わるという点です。
追加したスクリプトを確認します。
まず、カーソルオブジェクトに追加したCursorManagerクラスです。
・CursorManager.cs

            if (GazeManager.Instance.Hit)
            {
                // 2.b: SetActive true the CursorOnHolograms to show cursor.
                CursorOnHolograms.SetActive(true);
                // 2.b: SetActive false the CursorOffHolograms hide cursor.
                CursorOffHolograms.SetActive(false);
            }
            else
            {
                // 2.b: SetActive true CursorOffHolograms to show cursor.
                CursorOffHolograms.SetActive(true);
                // 2.b: SetActive false CursorOnHolograms to hide cursor.
                CursorOnHolograms.SetActive(false);
            }

            // 2.b: Assign gameObject's transform position equals GazeManager's instance Position.
            gameObject.transform.position = GazeManager.Instance.Position;

            // 2.b: Assign gameObject's transform up vector equals GazeManager's instance Normal.
            gameObject.transform.up = GazeManager.Instance.Normal;

GazeManagerがオブジェクトにヒットするとCursorOnHolograms側のオブジェクトを有効化し、ヒットしていないときはCursorOffHolograms側のオブジェクトを有効化する。
後はカーソルオブジェクトの位置を視線の位置に移動するだけです。
色の変化は2つのオブジェクトが交互に切り替わっているだけということです。


次に視線を制御するGazeManagerクラスです。
・CursorManager.cs

            // 2.a: Perform a Unity Physics Raycast.
            // Collect return value in public property Hit.
            // Pass in origin as gazeOrigin and direction as gazeDirection.
            // Collect the information in hitInfo.
            // Pass in MaxGazeDistance and RaycastLayerMask.
            Hit = Physics.Raycast(gazeOrigin,
                           gazeDirection,
                           out hitInfo,
                           MaxGazeDistance,
                           RaycastLayerMask);

以下で学習したRaycastの仕組みが利用されています。
bluebirdofoz.hatenablog.com


RaycastLayerMaskの設定は以下によると、衝突の無視を行う対象を選択するようです。
・Physics.Raycast
 https://docs.unity3d.com/jp/540/ScriptReference/Physics.Raycast.html

今回はDefault,Water,UIを無視するように設定しています。
これにより宇宙飛行士のアタリ判定にのみ、衝突判定が発生します。
・CursorManager.cs

            if (Hit)
            {
                // If raycast hit a hologram...

                // 2.a: Assign property Position to be the hitInfo point.
                Position = hitInfo.point;
                // 2.a: Assign property Normal to be the hitInfo normal.
                Normal = hitInfo.normal;
            }
            else
            {
                // If raycast did not hit a hologram...
                // Save defaults ...

                // 2.a: Assign Position to be gazeOrigin plus MaxGazeDistance times gazeDirection.
                Position = gazeOrigin + (gazeDirection * MaxGazeDistance);
                // 2.a: Assign Normal to be the user's gazeDirection.
                Normal = gazeDirection;
            }

ヒット時はヒットオブジェクトに合わせた距離と衝突角を設定します。
これをCursorManagerクラスで利用することで、カーソルがオブジェクトに沿う形で表示することができます。
ヒットしていない時は指定最大距離の位置と視線の角度をそのまま設定しているようです。


更に追加したInteractibleManagerクラスです。
・InteractibleManager.cs

        if (GazeManager.Instance.Hit)
        {
            RaycastHit hitInfo = GazeManager.Instance.HitInfo;
            if (hitInfo.collider != null)
            {
                // 2.c: Assign the hitInfo's collider gameObject to the FocusedGameObject.
                FocusedGameObject = hitInfo.collider.gameObject;
            }
(中略)
            if (FocusedGameObject != null)
            {
                if (FocusedGameObject.GetComponent<Interactible>() != null)
                {
                    // 2.c: Send a GazeEntered message to the FocusedGameObject.
                    FocusedGameObject.SendMessage("GazeEntered");
                }

こちらは衝突したオブジェクトに"GazeEntered"関数の呼び出しを実行していました。
試しに宇宙飛行士の各パーツのスクリプトを覗いてみると…
・Interactible.cs

    void GazeEntered()
    {
        for (int i = 0; i < defaultMaterials.Length; i++)
        {
            // 2.d: Uncomment the below line to highlight the material when gaze enters.
            defaultMaterials[i].SetFloat("_Highlight", .25f);
        }
    }

    void GazeExited()
    {
        for (int i = 0; i < defaultMaterials.Length; i++)
        {
            // 2.d: Uncomment the below line to remove highlight on material when gaze exits.
            defaultMaterials[i].SetFloat("_Highlight", 0f);
        }
    }

Interactible.csが既に追加されており、マテリアルの発効を行うGazeEntered()関数を保持していました。

手動でAstroManに追加したInteractible.csは現状、何も行っていないようでした。
後々のチュートリアルで利用するか、実際の講演ではこの追加時にInteractible.csの役割を説明したのでしょうか。

Blenderで3Dモデルを作成する(かんたん講座編その2)

今日も3Dモデリングを実施です。ある程度連続して続けないとすぐ忘れそうなので。
本日は顔のモデリングが完了し、体のモデリングを行いました。
f:id:bluebirdofoz:20170516005305j:plain


ボディ作成時に面取りの機能を使ってちょっと楽してみました。
blender-cg.net


面取りを行いたいところを選択します。
f:id:bluebirdofoz:20170516005327j:plain
面の部分が曲線のポリゴンに分割されました。
f:id:bluebirdofoz:20170516005334j:plain

しかし、頂点が等間隔なのでこのままだと中央部の平面が目立っています。
よって、ここで更に以下の記事に合った「Smooth Vertex」を利用します。
riotoqll.hatenablog.com

頂点を滑らかにしたいところを選択します。
f:id:bluebirdofoz:20170516005401j:plain
「Smooth Vertex」を何度か使うと全体的に奇麗な曲線になりました。
f:id:bluebirdofoz:20170516005406j:plain

このショートカットと機能を知っているか知っていないかでは5倍、10倍の作業時間差が生まれそうです。
知らず知らずのうちに他にも数々の無駄な作業を行っていると思うと、実に恐ろしい話です。。

Blenderで3Dモデルを作成する(かんたん講座編その1)

新しい技術習得です。
hololensのアプリを作るにあたっての私の目標に、自身が作成したキャラクタを登場させるというものがあります。
これを達成するには、ある程度の3Dモデルは自分で作れるようになれる必要があります。
という訳で、今回はblenderを使って3Dモデルを作成にトライしてみました。

筆者はそもそも3Dモデリングはしたことありません。blender自体も初めて触ります。
以下に従ってインストールを行いました。
blender-cg.net
blender-cg.net


blenderは無料で利用できる3DCGソフトですが、操作系が非常に複雑です。
特にショートカットキーが多く、覚えるのが大変そうです。
blender-cg.net
riotoqll.hatenablog.com


今回は以下を参考に実戦形式でblenderの使い方を覚えていきます。。
かんたんBlender講座


結果……半日ほど費やしましたが、本日は顔のモデリング途中で終了……。
f:id:bluebirdofoz:20170515004812j:plain


3Dモデリングがここまで大変とは。。
調べているとき、3Dモデラは人手不足という情報を目にしましたが、納得です。
これほどに覚える要素が多いツールを使いこなす技術者、かつ、美術センスを持つ人はそりゃあ貴重でしょう。
しかもまだまだボーンの設定、モーション、シェーダ、etc..。更に別種の技術も覚えていかないといけないんですから。

blenderの操作系は3DCGソフトの中でも特殊らしく、その点にも苦労させられました。
右クリックで編集が始まり、左クリックで確定…の箇所で何度右クリックを押してキャンセルになったことか。

しかし、目標を達成するには避けて通れない道です。まずは講座の完了を目指します。
ブログの更新頻度…というか、内容が今後薄くなる傾向になるかも。
(一応、本ブログの目的は筆者のモチベーション維持が最優先事項なので)

ARとVRデバイスを色々調べてまとめる(VIVE トラッカー)

ARとVRデバイスを色々調べてまとめる 周辺機器枠その4 Vive Tracker です。

Vive Tracker

f:id:bluebirdofoz:20170513214144j:plain
www.vive.com

スペック

本体スペック

ラッキング角度270度
電源完全充電時の使用可能時間:約6時間
通信方法USB、Bluetooth無線LAN

参考:HTC Tracker
   https://www.vive.com/jp/vive-tracker/
参考:「Tracker」の開発者向け資料が公開、動作の仕組みや仕様を確認できる
   http://www.dospara.co.jp/express/vr/338388

価格

Viveトラッカー(1個)1万2500円(税込み)

説明

HTC社から開発者向けに販売されている3Dトラッキングセンサデバイスです。
本機の利用にはHTC Vive環境が必須となります。
http://bluebirdofoz.hatenablog.com/entry/2017/05/04/164632
ベースステーションだけでなくHMD本体の接続も必要な模様)

現実世界にあるものをVR空間へトラッキング

本トラッキングセンサをアタッチしたオブジェクトはHTC Viveの仮想空間内で認識されます。
つまり現実世界の様々なものをVR空間に持ち込めるというデバイスです。
バットの先端にHTC Trackerを接続すれば、バットの位置や向きを仮想空間上で認識させて表示させるという事も可能です。

Vive Trackerで全身のトラッキング


Viveトラッカーを足に付ければ、疑似的な前進トラッキングも可能です。
全身トラッキング用のコードが既にHTC社により公開されているとのこと。
vrinside.jp


HTC Viveを所持している方はボディトラッキングのアイテムとしてHTC Viveを利用する選択肢も生まれそうです。
問題点は記事に書かれている通り、1万強のデバイスをトラッキング箇所毎に購入する必要があるということですが…。

ARデバイスとしても利用可能?

下記の記事では更にViveトラッカーとペーパークラフトを利用して現実世界でのテーブルゲームへの利用例がありました。
teruaki-tsubokura.com
 

見ているだけでも楽しいですし、トラッキング精度も非常に良いことが見て取れます。

Unityに設計おけるクラス設計を考える その3(Model)

本日は追いかけっこアプリの修正枠です。
設計を以前検討したものから適宜修正中です。修正内容は前回の記事に適宜反映していきます。
bluebirdofoz.hatenablog.com

本日はModel部分の実装です。
f:id:bluebirdofoz:20170512011032j:plain

以前紹介した記事に従い、Modelの通知の仕組みにUniRxを用いてみることにしました。
developers.cyberagent.co.jp

UniRxはAssetStoreから入手可能です。
qiita.com

データベースを以下のように実装できました。Model側はPresenterの存在を知らずに済むことが分かります。
・GameInformation.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

using UniRx;

namespace CatchAndRun.GameInformation
{
    public class GameInformation : MonoBehaviour
    {
        // 利用データベース
        public GameObject targetDatabase;
        private Database p_Database;

        // Use this for initialization
        void Start()
        {
            p_Database = targetDatabase.GetComponent<Database>();
            p_Database.init();
        }

        // ゲームモードの取得
        public IReadOnlyReactiveProperty<GameMode> GameMode
        {
            get { return p_Database.getGameMode(); }
        }

        // ゲームモードの設定
        public void setGameMode(GameMode gameMode)
        {
            p_Database.setGameMode(gameMode);
        }
    }
}

現在の悩みどころは追いかけっこロジックを何処に持つかということです。
メインカメラの位置を追跡したり、障害物をジャンプしたり。
最初はゲームロジックであると考えていましたが、キャラクターが持つ思考ロジックとして閉じた方が良いと思い直しました。
これならばModelにはキャラクターの位置などの冗長な通知が必要な情報は保持しないで済みます。

ただ気を付けないと、キャラクターが様々な役割を持ってしまい、再び煩雑なコードになることに繋がります。
こちらも以前紹介した記事で書かれていた「ゲームはViewの役割がブレやすい」の問題ですね。
yutakaseda3216.hatenablog.com

ARとVRデバイスを色々調べてまとめる(Matterport)

ARとVRデバイスを色々調べてまとめる 周辺機器枠その3 Matterport です。

Matterport

f:id:bluebirdofoz:20170511014509j:plain
matterport.com

スペック

カメラスペック

センサRGBカメラ×3、赤外線センサ×3
電源8~10時間
重量2.5kg

参考:matterport
   https://matterport.com
(どちらかというと3Dスキャンのサービスが凄いのでカメラ自体のスペックには余り意味なし)

価格

Matterport Pro 3Dcamera$3,600(約41万円)
ベーシックプラン月額 $49(約5900円)

説明

Matterport社がカメラの販売とサービス提供を行う3Dスキャンサービスです。

現実世界の空間を写真を使ってVR空間に再現

Matterport社が拘っているのは「現実世界の空間をVR空間に再現」ということのようです。
・カメラで撮るだけで行える3Dモデリング「Matterport」
 http://svs100.com/matterport/

公式ページでサンプルが公開されています。こんな3Dスキャンサービスが既にあった事に驚きです。
スペック等の詳細な情報は得られませんでしたが、備忘録として残しておきたくて思わず記事にしてしまいました。
・3Dギャラリー
 https://matterport.com/3d-space/lodge-grants-trail/

Googleストリートビューで利用

Googleも目を付けたようでパートナーシップを結んだようです。
jp.techcrunch.com

利用方法とフォーマット

以下に実際サービスを利用してみた事例をまとめた記事がありました。
現状、最も詳細かつ具体的な情報を得られる日本語ページだと思われます。
vr-lab.voyagegroup.com

これが手軽に利用できる時代が来ると、世の中は一体どうなるんでしょうか。
3Dモデルの精度が上がれば、もう建物系の観光地巡りなんかはVRデバイスとこれだけで十分なんじゃないかなぁ。
実家を撮影して、SNSと組み合わせれば仮想空間上で帰省して家族に会えたりとか。

ユニティちゃんトゥーンシェーダー2.0を試してみる

本日UnityChanページに立ち寄ると、「ユニティちゃんトゥーンシェーダー2.0」ver:2.0.0リリースの記事がありました。
・ユニティちゃんトゥーンシェーダー2.0
 http://unity-chan.com/download/releaseNote.php?id=UTS2_0

リリース直後です。トゥーンシェーダには興味があったので試してみることにしました。
ダウンロードを行うと、プロジェクトの形で取得できるのでサンプルシーンを開いてみます。
f:id:bluebirdofoz:20170510021753j:plain
絵的な塗りの3D世界が映し出されています。

さて、これってそのままhololensに持ってこれるのか?早速試してみます。
まずサンプルプロジェクトだとカメラが自動移動するスクリプトが組まれているのでCenterオブジェクトを無効化します。
f:id:bluebirdofoz:20170510021844j:plain
メインカメラを有効化し、いつも通り下記の設定を行います。
・Move Camera to Origin: アプリ起動時にカメラ位置を0,0,0にする
・Camera Clears to Black: カメラのBackgroundを黒にする

後はBuild SettingsでUWPアプリオブジェクトに切り替えます。
この辺りの設定は以下のチュートリアル101を参考にします。お決まりパターンです。
・HOLOLENS 初めての開発 “HOLO”WORLD
 https://azure-recipe.kc-cloud.jp/2016/12/hololens-tutorial1/

この時点でビルドしてみると、唯一「AutoBlinkforSD.cs」というクラスのみエラーが発生しました。
UWPで提供されていないライブラリを参照しているようです。
目パチのスクリプトという事なので今回はコメントアウトしました。

これでビルドは通り、実行できた…と思ったのですが、hololens上でアプリを動作しても画面が何も表示されません。
holographic Remotingで試してみるもやはり失敗…。

Unityが即座に落ちてしまうので詳細が追えませんが、D3D11というエラーが見えたのでDirectX系の問題?
やはりシェーダが関係していそうです。苦戦しそうなので今日はここで切り上げです。


裏ではユニティちゃん追いかけっこアプリの修正中です。
というよりも、本日は修正から着手していたのですが、新規に書くことが思い当たらなかったので急遽トゥーンレンダお試し枠にしました。
が、色々問題が出てきて手間取ったために結局、修正の方もほとんど勧められない結果に…。
二兎を追ってはいけない。