VR空間でモデルさんの笑い声を聞いてみる

「MMDモデルをくすぐれるVR体験ツール」に音声出力機能を追加しましたので、MikuMikuTickleV07として公開したいと思います。
 VRHMDがなくても起動できるようになりましたので、VRHMDを持っていない方にもお試しいただければと思います。
 しかしながら、VRHMDがない状況では遠近感がないため、LeapMotionによる自分の手でMMDモデルをくすぐるのには多少の慣れが必要かと思います。また、VRHMDに比べてキャラクターの存在感が大幅に減少してしまいますので、やはりVRHMDはあった方がいいと思います。
 MikuMikuTickleV07は、以下のリンクからダウンロードできます。
MikuMikuTickleV07 ダウンロード
 V06からの主な改善点は、以下のとおりとなります。

・VRHMDがなくても起動できるようにしました
・音声を出せるようにしました
・モデルの動きをカスタマイズできるようにしました
・接触認識エリアの配置方法を変更し、上半身のエリアを2分割しました
・二の腕をくすぐれるようにしました
・足をくすぐられた時の動きを改善しました
・時計を追加しました
・シェーダーのコンパイルをビルド前に行うようにしました
・目のボーンのないモデルもこっちを向けるようにしました
・「笑い」モーフのないモデルは「笑う」モーフを使って笑わせるようにしました
・[P]キーを押した時、UIで変更した位置に加えて角度もリセットするようにしました
・他(不具合対応等)

 ミニメロンが動作確認に使用した環境は、以下のとおりです。

・デスクトップPC
 (OS:Windows10 Home(64bit)/CPU:Intel(R) Core(TM) i3-3240 3.4GHz/
  メモリ:4.0GB/GPU:NVIDIA GeForce GTX 650)
・Leap Motion
・OSVR Hacker Development Kit v1.4
・Oculus Rift (DK1)
 これらのうち、OSVR HDKv1.4とOculus DK1は、どちらか片方だけあればよく、逆に二つ同時に使う事はできません。
 残念ながらHTC Viveでは動作確認ができておらず、本当に問題なく動くかどうかは分からないのですが、お持ちの方はぜひ試してみて頂きたいと思います。

 開発環境としては、前回までと同様に、Microsoft Visual Studio Express 2012 for Windows Desktopを使用します(VS2013以降でも同様の手順で動作させる事ができるのではないかと思うのですが、未確認です)。

 動作させるためには以下のライブラリやSDK等も必要です。
 今回、モデルさんの声を出せるようにしたわけですが、その時にしゃべってほしい内容は、状況によって様々なのではないかと思います。
 また、しゃべらせたい内容によっては、モデルの動作をある程度変更したい場合もあるでしょう。
 そこで、どのような場合にどのような音声を出力し、その時にモデルをどのように動作させるかといった事を設定する為に、Luaというスクリプト言語を使用する事にしました。その為、Lua用のライブラリが追加になっています。
・OculusSDK(バージョン 0.2.5c)
 →OculusRift DK1を使うためのライブラリです。OculusRift DK1を使わない場合は、なくても大丈夫です。
・OSVR SDK for Windows(32bit)
 →くすぐり漫画をOSVRな空間で読むに書いたとおり、http://osvr.github.io/using/ からダウンロード・インストールします。
・boost_1_61_0
 →くすぐり漫画をOSVRな空間で読むに書いたとおり、http://www.boost.org/users/download/#live からzipファイルをダウンロードし、その中にあるboost_1_61_0というフォルダを、C:\の直下に置きます。
 使うのはヘッダファイルのみですので、ビルド作業等は不要です。
・OpenVR SDK
 →くすぐり漫画をOpenなVR空間で読むに書いた通り、https://github.com/ValveSoftware/openvrからダウンロードし、圧縮ファイルの中のopenvr-masterフォルダをCドライブの直下に置きます。
・DirectXTex
 →https://github.com/Microsoft/DirectXTex/releases からダウンロードして、Cドライブの直下にDirectXTexというフォルダを作り、その中にダウンロードした圧縮ファイルの中身をすべてコピーします。
 (最新版にはVS2012用の.slnファイルが含まれていないようなので、旧版をダウンロードした用がよいでしょう。私が使用しているのはFebruary 24, 2014リリースの版です)  VisualStudioExpress2012を立ち上げ、ファイルメニュー→プロジェクトを開く で、DirectXTexのフォルダの中にあるC:\DirectXTexフォルダの中のDirectXTex_Desktop_2012.slnを開いた後、メニューバーのすぐ下のツールバーの真ん中あたりにある「Debug」と表示されているリストボックスをクリックし、出てくる項目の中から「Release」を選択します。
 その後、ビルドメニュー→ソリューションのビルド を選択します。
 ビルドが正常に終了したら、ファイルメニュー→ソリューションを閉じる でプロジェクトを閉じます。
・Leap_Motion_SDK_Win_3.1.3
 →LeapMotionの新しいSDKで、Orionとも呼ばれています。
 まだ導入していない場合は、https://developer.leapmotion.com/ にログインしてダウンロードし、圧縮ファイルの中にあるLeap_Motion_SDK_Win_3.1.3というフォルダをCドライブの直下に置きます。そして、そのフォルダの中にあるLeap_Motion_Setup_Win_3.1.3.exeを実行し、LeapMotion用のドライバを更新します。
・Bullet(バージョン2.82)
 →現在の最新バージョンは2.86のようですが、MikuMikuTickleでの動作は未確認です。
 2.82は現在も https://github.com/bulletphysics/bullet3/releases/tag/2.82 からダウンロードできるようですが、フォルダの名前が若干変わっているかもしれません。
 今回は、モデルさんをくすぐるついでにスカートをめくってみるでダウンロードし、Windows8.1でモデルさんをくすぐるにはで行った方法でビルドしたものを使用します。
・lua-5.3.4_Win32_dllw4_lib
 Luaスクリプトを実行するためのライブラリです。
http://luabinaries.sourceforge.net/download.html から lua-5.3.4_Win32_dllw4_lib.zip をダウンロードし、中身の lua-5.3.4_Win32_dllw4_lib をCドライブの直下に置いて下さい。
・MMDモデル
 今までデモ動画で使用させて頂いた
 Tda式初音ミク・背中見せアペンド(http://www.nicovideo.jp/watch/sm29211145)
 Tda式初音ミク・アペンド Ver1.00(http://seiga.nicovideo.jp/seiga/im2018614)
 Lat式ミクVer2.31(http://www.nicovideo.jp/watch/sm11205201)
の他にも多数のMMDモデルで動作確認をしております。
 今回、目のボーンのないモデルもこっちを向けるようにしたり、「笑い」モーフのないモデルを「笑う」モーフで笑わせるようにした事により、V06では問題のあった「電脳少女シロ(ハロウィンダンスVer.)」(http://3d.nicovideo.jp/works/td31676)も正常に召喚する事ができるようになりました。
 なお、MMDモデルの中にはMMD以外のツールでの読み込みが禁止されているものもありますので、使用する前にモデルに付属しているReadme等を確認するようにして下さい。

[動作手順]

1、MikuMikuTickleV07プロジェクトの作成
 VisualStudioExpress2012のファイルメニュー→新しいプロジェクト を選択します。
 テンプレートからVisual C++ を選択し、Win32プロジェクトを選択して、名前欄にプロジェクト名(例えばMikuMikuTickleV07)を入力し、「ソリューションのディレクトリを作成」にチェックが入っている事を確認し、OKボタン→次へボタン→追加のオプションの「空のプロジェクト」をチェック(この時Security Development Lifecycleにチェックが入っている場合はチェックを外す)→完了ボタン の順に押します。

2、リリースビルドへの切り替え
 メニューバーのすぐ下のツールバーの真ん中あたりにあるリストボックスに「Debug」と表示されている場合は「Release」に変更します。

3、ソースの準備
 MikuMikuTickleV07のダウンロード圧縮ファイル(mmt_v07.zip)の中の、MikuMikuTickleV07というフォルダに含まれている全ファイルを、MikuMikuTickleV07.slnの存在するフォルダの中にある、MikuMikuTickleV07というフォルダにコピーします。

4、インクルードディレクトリの設定及びプリプロセッサの定義
 VisualStudioの画面の右の方にあるソリューションエクスプローラという枠の中の、一番上に表示されているプロジェクト名(MikuMikuTickleV07)をクリックして選択状態にし、プロジェクトメニュー→プロパティでプロジェクトのプロパティを表示させます。
 「構成プロパティ」の中の「C/C++」の中の「全般」をクリックし、プロパティページの右側の枠の「追加のインクルードディレクトリ」をクリックします。枠の右端に現れる下向きの矢印のようなマークをクリックし、「編集」を選択して表示されるダイアログボックスの上の枠に、以下の8行の内容を入力します。

C:\Leap_Motion_SDK_Win_3.1.3\LeapSDK\include
C:\OculusSDK\LibOVR\Include
C:\DirectXTex\DirectXTex
C:\bullet-2.82-r2704\src
C:\Program Files (x86)\OSVR\SDK\include
C:\boost_1_61_0
C:\openvr-master\headers
C:\lua-5.3.4_Win32_dllw4_lib\include

 ただし、OculusSDKを持っていない場合は、2行目を除いた7行を記述します。
 入力が終わったら、OKをクリックします。

 OculusSDKを持っていない場合は、「構成プロパティ」の中の「C/C++」の中の「プリプロセッサ」をクリックし、プロパティページの右側の枠の「プリプロセッサの定義」をクリックします。枠の右端に現れる下向きの矢印のようなマークをクリックし、「編集」を選択して表示されるダイアログボックスの上の枠に、
WITHOUT_LIBOVR
という文字列を追加します。
 入力が終わったら、OKをクリックします。

5、ライブラリディレクトリの設定
 「構成プロパティ」の中の「リンカー」をクリックし、プロパティページの右側の枠の「追加のライブラリディレクトリ」をクリックします。枠の右端に現れる下向きの矢印のようなマークをクリックし、「編集」を選択して表示されるダイアログボックスの上の枠に以下の7行の内容を入力します。

C:\Leap_Motion_SDK_Win_3.1.3\LeapSDK\lib\x86
C:\OculusSDK\LibOVR\Lib\Win32
C:\DirectXTex\DirectXTex\Bin\Desktop_2012\Win32\Release
C:\bullet-2.82-r2704\lib
C:\Program Files (x86)\OSVR\SDK\lib
C:\openvr-master\lib\win32
C:\lua-5.3.4_Win32_dllw4_lib

 ただし、OculusSDKを持っていない場合は、2行目を除いた6行を記述します。
 入力が終わったら、OKをクリックします。
 その後、プロパティページのOKボタンをクリックします。

6、ソースをプロジェクトに追加
 先ほどコピーしたMikuMikuTickleV07のファイルのうち、以下のファイル(*.cpp、*.hの全て)を プロジェクトメニュー→既存項目の追加 でプロジェクトに追加します。

DXCommon.h
LMCHand.cpp
LMCHand.h
LuaAudio.cpp
LuaAudio.h
MikuMikuTickle.cpp
pmd.cpp
pmd.h
PMDXBullet.cpp
PMDXBullet.h
PMDXWork.cpp
PMDXWork.h
pmx.cpp
pmx.h
SensorClient.cpp
SensorClient.h
UIPanels.cpp
UIPanels.h
vmd.cpp
vmd.h
VMDWork.cpp
VMDWork.h

7、スタート→Microsoft Visual Studio 2012→VS2012の開発者コマンドプロンプト を起動し、CDコマンドでMikuMikuTickleV07.slnの存在するフォルダに移動し、sdrcompile.bat を実行します。
これにより、sdr_pmdx_vs_main.h、sdr_ps_main.h、sdr_ps_main_OSVRDist.h、sdr_ps_main_OVRDist.h、sdr_vs_main.h、sdr_vs_main_OSVRDist.h が生成されます。

8、設定ファイルの編集
 mmt_v07.zipの中のreadme.txtファイルを参考に、先程コピーしたいくつものファイルの中に含まれる設定ファイル(mmtconfig.txt)を必要に応じて編集します。
 1〜4行目は、使用するVRHMDに関する設定です。
 配布時は

HMD=None
#HMD=OSVR
#HMD=OculusDK1
#HMD=OpenVR
となっています。行頭の#は、その行が有効でない事を意味します。
上記の設定では1行目の HMD=None が有効になっており、これはVRHMDを使用しない事を示しています。
OSVRを使用する場合は1行目の行頭に#を挿入し、2行目の#を削除して、HMD=OSVRを有効にします。
Oculus Rift DK1 を使用する場合は同様に3行目の HMD=OculusDK1 を、HTC Vive を使用する場合は4行目の HMD=OpenVR を有効にします。

 5行目の
SleepPerFrame=5
 は、1フレーム描画毎に待ち時間を5ミリ秒入れる事を指定しています。0にすると、待ち時間なしになります。
 CPUパワーに余裕がなくてOSVRのポジトラが不安定な場合、この数字を大きくする事により安定する場合があります。
 ただし、その分フレームレートは低下します。

 6〜8行目は、LeapMotionのデータ取得に関する設定です。
 詳細については、readme.txtをご覧ください。
 ここを変更する事により、他のPCからLeapMotionのデータを取得できるようになるのですが、通常は素直にこのまま使用し、LeapMotionはMikuMikuTickleを実行するPCに接続するのがよいでしょう。
 もともとはOSVRな空間でモデルさんをくすぐってみるで、CPU負荷低減のために入れた機能なのですが、OSVR HDKでカノジョの部屋へ行ってみるに記載したとおり、OSVRServerの設定ファイル(osvr_server_config.json)にsleep設定を入れる方が効果が大きいです。

 9行目の
#ScriptPath=luasample\sample1.lua
については、後ほど説明します。

 編集が終わったら、上書き保存します。

9、VRHMDの準備
 VRHMDを使用する場合は、VRHMDの電源を入れます。
 HTC Viveの方は、Steam VRを起動します。
 SteamVRを使用せずにOSVR HDKを使用する方はOSVR Serverを立ち上げます。ダイレクトモードになっている場合はC:\Program Files (x86)\OSVR\SDK\binの下にあるDisableOSVRDirectMode.exeをダブルクリックして解除します。
 逆に、OSVRでもSteamVRを使用する場合はダイレクトモードにするためにEnableOSVRDirectMode.exeをダブルクリックしてから、SteamVRを起動します。
 LeapMotionはVRHMDの前面に貼り付け、VRHMDと同じPCに接続します。

10、実行
 デバッグメニュー→デバッグなしで実行 で実行します。
 最初は「leap.dllがない」等のエラーが出ますので、その場合は C:\Leap_Motion_SDK_Win_3.1.3\LeapSDK\lib\x86 から以下のファイルを実行形式(MikuMikuTickleV06.exe)と同じフォルダにコピーします。

Leap.dll
msvcp120.dll
msvcr120.dll

 また、以下のファイルをC:\Program Files (x86)\OSVR\SDK\bin からコピーして、実行形式(MikuMikuTickleV07.exe)と同じフォルダに置きます。
osvrClient.dll
osvrClientKit.dll
osvrCommon.dll
osvrUtil.dll

 更に、以下のファイルをC:\openvr-master\bin\win32 からコピーして、実行形式(MikuMikuTickleV05.exe)と同じフォルダに置きます。
openvr_api.dll

 更に、以下のファイルをC:\lua-5.3.4_Win32_dllw4_lib からコピーして、実行形式(MikuMikuTickleV07.exe)と同じフォルダに置きます。
lua53.dll

 コピーが終わったら、再度、デバッグメニュー→デバッグなしで実行 で実行します。
 ファイル選択ダイアログボックスが出てくるので、召喚したいモデルさん(MikuMikuDance用PMDファイル又はPMXファイル)を選択します。
 SteamVRを使用する場合、デスクトップ画面は真っ白になったままとなりますが、しばらくすると、VRHMDにはMMDモデルが表示されます。
 今回、LeapMotionで認識された手でくすぐれるモデルさんの身体の部位として、二の腕が追加となっています。
 また、他の部位に関しても、くすぐりを認識するための接触認識エリアの配置方法が少し変わっています。
 V06まではボーンの位置関係のみから推測していたのですが、V07では身体の形状により近い配置とするために、ポリゴン位置も考慮するようにしてみました。
 これにより、モデルを選択してから画像を出す前に行う接触認識エリアの配置の為の計算にかかる時間が少し増えてしまっていますが、シェーダーのコンパイルをビルド前に行うようにした事により、モデル選択から画像が出るまでの待ち時間のトータルとしては、10〜15秒程度短縮されていると思います。
 VR空間内で時間が分からなくなった時は、UIパネルを表示すれば現在時刻を確認できます。
 また、VRHMDを使用している時に上を見上げたり下を見降ろしたくなった時は、自分の首を向ければよいのですが、VRHMDを使用していない時にそうしたくなった場合は、[3]キーと[4]キーで視線の上下の向きを変える事ができます。

 その他、操作方法や、モーション記録機能で記録されたVMDの利用方法等に関しましては、readme.txtを参照頂きたいと思います。

[VisualStudioExpress2012を立ち上げなくても実行できるようにする]
 MikuMikuTickleを使う度にいちいちVisualStudioExpress2012を立ち上げるのは面倒だと思いますので、VisualStudioExpress2012を立ち上げなくてもMikuMikuTickeを起動できるようにする方法を紹介します。

1、実行ファイルとDLLファイルのコピー
 実行形式のあるフォルダ(先ほど.dllファイルをコピーしたフォルダ)の中にあるファイルのうち、.pdbの拡張子のついたもの以外の全てを任意のフォルダにコピーします。

2、設定ファイルのコピー
 ソースをコピーしたフォルダから以下のファイルを、1のコピー先のフォルダにコピーします。

mmtconfig.txt
 この後は、1のコピー先のフォルダでMikuMikuTickleV07.exeファイルをダブルクリックすればMikuMikuTickleが起動します。

[モデルさんの笑い声を聞いてみる]
 新機能である音声出力機能を使うには、Luaによるスクリプトを書かなければならないのですが、モデルさんがくすぐられる時に笑い声を上げさせるだけであれば、同梱のサンプルスクリプトを使って実現できます。

 まず、mmt_v07.zipの中の、luasample というフォルダを、[VisualStudioExpress2012を立ち上げなくても実行できるようにする]で作ったフォルダの中にコピーします。
 次に、mmtconfig.txt を開いて、
#ScriptPath=luasample\sample1.lua
となっている行の先頭の#を削除し、保存します。
 更に、luasampleフォルダの中に、笑い声の音声ファイルを laugh.wav 又は laugh.mp3 という名前で配置する必要があります。
 試しに 効果音ラボ様の「声素材 - 日常セリフ(元気な女の子)」のページ(https://soundeffect-lab.info/sound/voice/line-girl1.html) から、「笑い」の中の「あははははっ!」(line-girl1-ahahaha1.mp3)をダウンロードし、名前を laugh.mp3 に変更して luasample フォルダの中に置いてみましょう。
 これで、MikuMikuTickleV07.exeをダブルクリックで立ち上げ、VR空間内のモデルさんをくすぐると、笑い声が聞こえるようになるはずです。

 luasample フォルダには sample1.lua 以外にもサンプルスクリプトが2つほど含まれていますが、それらはMikuMikuTickleV07 がLuaスクリプトの為に提供する各種関数の使用例を示すためだけのものであり、実用性はありません。
 MikuMikuTickleV07 の機能をもう少しまともに活用したLuaスクリプトの書き方については、今後少しずつ紹介していきたいと思います。

(2018/9/18)

 ……というわけだったのですが、紹介動画作成の為にいろいろ試していたところ、不具合がいくつか見つかりました。
 今回は紹介動画アップ前なので、ダウンロードファイル(ZIP)を上書き修正しました。既にダウンロードされた方は、申し訳ありませんが、再ダウントードをお願いします。
 修正後のZIPファイルは、luasampleフォルダの中のサンプルとして sample4.lua が追加になっています。
 もしもダウンロードしたZIPファイルに sample4.lua が含まれていない場合は古いZIPですので、ブラウザのキャッシュをクリアしてから再度ダウンロードをお願いします。

修正した不具合は、いずれもLuaスクリプトの為にMikuMikuTickleが提供する関数の動作に関するもので、以下のような内容です。
・MMTF.IsTickled()の引数に4〜13を与えた時に正しい戻り値が得られない
・MMTF.GetTouchAreaNameByIdx()に12、13を与えると、戻り値がnilになる
・MMTF.GetTouchAreaIdxByName()で検索に失敗すると、プログラムが異常終了する
・readme.txt内の MMTF.GetTouchAreaNameByIdx() 及び MMTF.GetTouchAreaIdxByName() の説明で、エリア名 "armL", "armR" が抜けている
・サンプルLuaスクリプト sample3.lua による表示内容に誤りがある(MMTF.GetEyeBasePos()及びMMTF.GetEyeBaseYaw()の値の左に、それらの関数名ではなく"InitialHeadPos:","InitialHeadYaw:"と表示される)

修正したファイルは MikuMikuTickle.cpp と readme.txt、追加したファイルは sample4.lua です。

 sample4.lua は、モデルさんの身体の各部がくすぐられているかどうかを、接触認識エリア単位で表示するものです。これによりMMTF.IsTickled()の不具合が修正された事を確認できます。
 sample2.lua〜sample3.lua と同様に、実用性はありません。

(2018/10/3)

 ……というわけだったのですが、先日、紹介動画をアップしました。
【ニコニコ動画】VR空間の櫻花アリスに余計な事して笑わせてみた
 今回はキャラクターの声及びモデルさんに、櫻花アリスを使わせて頂きました。
 タイトルが「余計な事」となっているのは、モデルさんがくすぐられた後に「余計な事してないで、早く助けなさいよ」と言っているからで、今回追加した機能が余計な機能というわけではありません。
 MikuMikkuTickleには今のところ、音声認識機能がないので、キャラクターが人の話す言葉に対して返事をする事はできないのですが、くすぐると笑ってくれるのはもちろん、ユーザがキャラクターに最初に近づいた時にキャラクターが「やっと助けに来てくれたのね」と言ったり、くすぐられた直後に「ちょっと、いきなり何すんのよ」と言うなどして、ユーザーの動きに対してキャラクターが言葉を返してくれる事により、キャラクターとのある種のコミュニケーションを楽しむ事ができる事が分かっていただけるのではないかと思います。
 そして、そのようなコミュニケーションの内容は、音声ファイルを入れ替えたり、Luaスクリプトを書き換えたりする事により、人それぞれの好みに合うようにある程度変更する事ができるのです。
 これまでにも「俺の嫁」とコミュニケーションができるソリューションはいくつか存在していたと思いますが、それらは言葉による会話が中心だったのに対して、MikuMikuTickleV07で実現するキャラクターとのコミュニケーションはユーザーの指によるくすぐりや、お口でのペロペロなどによるものである事と、スクリプトや音声データの変更などによって会話内容をカスタマイズができる事、相手がMMDモデルである事、VRHMDに対応している事、キャラクターの動きを記録して動画制作に使える事などが、従来の「俺の嫁」との会話ソリューションとは異なる特徴なのではないかと思います。

 今回の動画用に作成したLuaスクリプトでは、sample1.luaで使用している関数以外に、以下のMikuMikuTickle提供関数を使用しています。
 それぞれの関数の詳細につきましてはreadme.txtを参照頂ければと思います。

・MMTF.SetInitialEyeBasePos()
 VR空間内のユーザーの初期位置を設定するのに使用しています。
・MMTF.SetInitialEyeBaseYaw()
 VR空間内のユーザーの初期の向きを設定するのに使用しています。
・MMTF.GetHeadMatrix()
 現在のユーザーの頭の現在の姿勢行列を取得する関数ですが、動画ではキャラクターに最初に近づいた時に台詞を言わせる為、ユーザーの頭の位置を求めるのに使用しています。
・MMTF.GetNumOfTouchArea()
・MMTF.GetMouthPos()
・MMTF.PosIsInTouchArea()
 動画では、これらの関数を組み合わせて使用する事により、お口でペロペロされているのがどのエリアか判断しています。

 readme.txtでは他にも多くの関数について説明しており、使用例をsample2.txt〜sample4.txtで示していますが、とりあえず上記とsample1.luaで使用している関数(音声出力など)を使えば動画で紹介したのと同様の動作を実現できると思います。
 これを参考に、皆さんもご自分の嫁との理想のスキンシップを追究してみて頂ければと思います。

(2018/10/18)

戻る