目次
mocopiとは
mocopiは、ソニーが開発・販売している小型・軽量のモバイルモーションキャプチャーデバイスです。6つのセンサーを頭、両手首、腰、両足首に装着することで、全身の動きをリアルタイムでトラッキングし、スマートフォンアプリを通じて3Dキャラクターやアバターに反映させることができます。
主な特徴
- 小型・軽量: 直径約3cm、重さ8gのセンサーを6箇所に装着するだけで、フルボディのモーションキャプチャーが可能です。
現在ではフルボディーのモーションキャプチャ以外にも、手首のセンサーを膝上に装着することで、下半身の動作を重点的にキャプチャするモードや、逆に上半身を重点的にキャプチャするモードも実装されています。
mocopi 2セットを同時装着し、それぞれ下半身モードと上半身モードに設定すれば最大10点のモーションキャプチャが可能かもしれません(未実証) - 手軽さ: スタジオや特殊な機材が不要で、スマートフォンとBluetooth接続するだけでどこでも使用可能。屋内外を問わず、普段着のままでモーションキャプチャーが実現できます。
- 高精度な動作推定: 加速度センサーとジャイロセンサーに加え、ソニー独自のAIアルゴリズムを使用して、センサーを装着していない関節(肘や膝など)の位置も正確に推定します。
また、現在ではSDKを利用すればセンサーの生データ(加速度と角速度)も取得することが可能ですので、加工されていないデータが必要な場合にも対応可能です。 - バッテリー持続時間: 1回の充電で最大10時間使用できるため、長時間の撮影にも対応可能です。
用途
- VTuberやメタバース: mocopiは特にVTuberやメタバース関連サービスでの活用が期待されており、リアルタイムでアバター操作や動画コンテンツ制作が可能です。
- アニメーション制作: アニメ制作現場でも導入されており、手軽にモーションデータを取得し、CGキャラクターに反映させることができます。
- フィットネスやイベント: モーションデータを活用したフィットネスアプリやイベントなど、多様な分野での応用も進んでいます。
今回は屋外でのランニングフォームをリアルタイムにキャプチャーすることを目的としています。
技術的特徴
- リアルタイムトラッキング: センサーから取得したデータはスマホアプリで処理され、そのままリアルタイムで3Dキャラクターに反映されます。これにより、即座にモーションデータを確認したり、外部ツールと連携してVTuber配信やVRゲームなどに利用できます。
通常はmocopiとスマートフォンをbluetooth接続によりリアルタイムトラッキングし、さらにスマートフォンとPCをWifiで接続することでPCでもリアルタイムトラッキングすることが可能です。
今回はスマートフォン(iPhone)とPCをLTE回線とVPNで接続することで、iPhoneとPCが遠隔地にある場合でもリアルタイムトラッキングするシステムを構築します。 これにより、Wifiの電波が届かないような長距離でも、携帯の電波が届く場所であればどこでもリアルタイムにトラッキングすることが可能になります。 - 多様な連携: UnityやUnreal Engineなどの開発環境とも連携できるSDKが提供されており、プロフェッショナルなコンテンツ制作にも対応しています。
Godotとは
Godot(ゴドー)は、オープンソースかつクロスプラットフォーム対応の2D/3Dゲームエンジンです。2014年にMITライセンスのもとで公開されました。
特徴
- 完全無料: Godotは商用利用を含めて無料で使用でき、ロイヤリティやライセンス料が発生しません。
- クロスプラットフォーム対応: Windows、macOS、Linux、iOS、Android、Webブラウザ(WebGL)など、多様なプラットフォームに対応しています。
- 2D/3Dゲーム開発: Godotは2Dと3Dの両方に強みを持ち、特に2Dゲームの開発では高い評価を得ています。最新バージョンでは3D機能も大幅に強化されています。
- 独自のスクリプト言語GDScript: Pythonに似た構文を持つGDScriptを使用してゲームを開発します。C#やC++などもサポートしており、柔軟なプログラミングが可能です。C#を利用してプログラミングする場合には、.NET版を利用する必要があり、対応するプラットフォームが限定されます。
- 軽量かつ高速: エンジン自体が軽量で、低スペックのマシンでも快適に動作します。また、拡張性が高く、プロジェクトの管理やバージョン管理との相性も良好です。
レンダリングと物理エンジン
- Vulkan対応: 最新バージョンではVulkanによる高品質なレンダリングが可能で、リアルタイムで美しい3Dグラフィックスを描画できます。また、2D用の独立したグラフィックスエンジンも備えています。
- 物理エンジン: 3D物理演算にはBulletエンジンを採用し、リアルな物体の動きを再現できます。2D/3D両方でRigidBodyやColliderなどの物理コンポーネントが利用可能です。
用途と将来性
Godotはインディーゲーム開発者や学生に人気があり、その軽量さと使いやすさから広く利用されています。現在は商用ゲームにも徐々に採用され始めており、日本でも注目が高まっています。Godotは完全無料でありながら高機能で、多様なプラットフォームに対応しているため、小規模なプロジェクトから本格的なゲーム開発まで幅広い用途に適しています。
Godotにてmocopiのデータをリアルタイムトラッキング
Godotにてmocopiから送信されるUDPのモーションデータをリアルタイムに表示させます。
GotodでのUDPデータ受信には次のGDExtensionを利用しました。
GDExtensionの使い方はリンク先に詳しい解説がありますので、そちらを参照してください。
このGDExtensionをそのまま利用すると、最新のmocopiアプリでは動作しませんでした。ただし、BVH Senderアプリを使って送信したデータでは動作しました。
そこで、UDPデータをキャプチャして比較すると次の相違点がありました。
最新mocopiデータの場合は、uutmブロックとbtrsブロックの間にtmcdブロックが追加されています。GDExtensionは、tmcdブロックに対応していないため、データ解析に失敗しアニメーションが表示されない状態になっていました。
そこで、tmcdブロックがある場合にはスキップし、続きのbtrsブロックから解析を継続するようGDExtensionのlibのソースを次のように変更しました。
なお、tmcdブロックがどのような情報(タイムコード?)なのかは調査していません。
func _decode_btrs(stream: StreamPeerBuffer) -> bool:
# ブロックのサイズを取得
var size = stream.get_u32()
# ブロックの識別子を確認
var block_name = stream.get_string(4)
# tmcdブロックを検出した場合は6バイトスキップ
if block_name == "tmcd":
print_debug("tmcdブロックを検出: 6バイトをスキップします")
stream.get_data(6) #6バイトスキップ
# 次のブロック読み込み
size = stream.get_u32()
block_name = stream.get_string(4)
if block_name != "btrs": return false
var btrs_stream: StreamPeerBuffer = StreamPeerBuffer.new()
var r = stream.get_data(size)
if r[0] != OK: return false
btrs_stream.data_array = PackedByteArray(r[1])
ary_btdt.clear()
ary_btdt.resize(MOCOPI_BONE_COUNT)
valid_btdt = false
for i in range(MOCOPI_BONE_COUNT):
size = btrs_stream.get_u32()
if btrs_stream.get_string(4) != "btdt": return valid_btdt
var bnid: int = _parse_s16(btrs_stream, "bnid")
var o: MocopiBtdt = MocopiBtdt.new(bnid)
size = btrs_stream.get_u32()
if btrs_stream.get_string(4) != "tran": return valid_btdt
o.quat.x = btrs_stream.get_float()
o.quat.y = btrs_stream.get_float()
o.quat.z = btrs_stream.get_float()
o.quat.w = btrs_stream.get_float()
o.vct3.x = btrs_stream.get_float()
o.vct3.y = btrs_stream.get_float()
o.vct3.z = btrs_stream.get_float()
ary_btdt[o.bnid] = o
valid_btdt = true
btdt_count += 1
return valid_btdt
人体3Dモデル
今回利用する3DモデルはAdobe Mixamoのモデルを利用します。
Mixamoからダウンロード可能なフォーマットはfbxですが、GDExtensionが想定しているモデルはvrmですので、Blenderにてfbxをインポートし、vrmでエクスポートすることで変換可能です。
mocopiとPCをWifiで接続
mocopiとPCのwifi接続は、説明書どおりに行えば特に問題なく繋がると思います。
このモーションキャプチャは通常モードでキャプチャしているため、頭、腰、両手首、両足首にセンサを取り付けています。
この状態でも膝の動き等も再現されています。
mocopiとPCを携帯回線で遠距離接続
Wifi接続の場合にはiPhoneとPCを同じWifiに接続する必要があります。Wifiは屋外の見通しのよい状態でも数十メートル程度しか接続できません。そのため、広いフィールドをランニングする場合には、リアルタイムでのモーションキャプチャは困難であり、スマートフォンに記録したデータをあとで抜き出して動作を確認する必要があります。
今回は、iPhoneをWifi接続するのではなく携帯回線(LTE回線)を使ってデータを送信します。特別な回線は必要なく、通常の携帯回線で問題ありません。
ただし、iPhoneと受信用のPCの間はWifiと同じように閉じたネットワークの状態にする必要があります。そのために、VPNというネットワークの機能を利用します。VPNを利用することで、携帯回線(インターネット回線)を利用しているにもかかわらず、Wifiと同じようにスマートフォンとPCを同じネットワーク内にあるように利用することが可能になります。
VPNを利用する方法はいろいろありますが、今回はTailscaleというサービスを利用します。
TailscaleはWindows、Mac、Android、iPhoneなどの環境に対応しており、それぞれに専用のアプリがあるため、ダウンロードしてVPNを設定します。設定自体はそれほど難しくはなく、同じアカウントでログインして接続すれば、自動的にVPNのネットワークが構築されます。
今回は、iPhoneとWindowsにアプリをインストールし、同じTailscaleのアカウントでログインすることで、iPhoneとWindows PC間にVPNを構築し、Wifiで接続した場合と同じようなネットワーク環境を構築します。
VPNを張った状態でWindows PCのIPアドレスを調べ、iPhoneのmocopiアプリのデータ送信先のIPアドレスに設定します。
これで、iPhoneに携帯電波が入る範囲内であれば、リアルタイムモーションキャプチャが可能になります。
次の動画はVPNでの動作検証です。Wifiが届かない範囲でもモーションキャプチャ可能であることを確認できました。今回は使用したPCのスペックが低かったため、Godotでの3Dモデル表示と画面の録画を行うと処理が重くなり、録画がコマ落ちしてしまいました。実際のモーションキャプチャアニメーションはもっとスムーズに動作しました。ただし、携帯回線がIoT用の低速度の回線であったことと無料のVPNサービスを利用したため、おそらく通信速度があまり出ておらず時々、コマ落ちしました。