はじめまして。インターン生の平島です!
「『レディー・プレイヤー1』の世界は近い?3つのアイテムが鍵になる」で紹介されている
Hi5 VR Gloveを使って指の位置をiPhone上で可視化してみました。
1.Hi5 VR Gloveとは?
指の動きを高精度でVR空間に表示できるグローブ型コントローラーです。
色々なポーズがとれます。
VIVEで座標取得して表示されています。
2.実装方針
以下の流れで実装してみました。
1.基準点となるVIVEトラッカーから各指への相対座標を取得
2.相対座標をサーバー経由でiPhoneに送信
3.iPhone上で各指の座標にオブジェクトを表示
VIVEの座標系とiPhoneの座標系はそれぞれ別のものです。
そのため、なにも考えず「VIVE座標系における各指の座標」をiPhoneに送信しても正しく
表示がされません。
そこで両座標系の軸合わせのため、基準点となるトラッカーを用意しました。
●相対座標取得
【失敗例】
Transform型の変数を用意してトラッカー、手の甲、指を取得します。
手の甲、指の座標からトラッカーの座標を引けば相対座標がわかりますが(※)
Transform型同士の引き算はできないのでそれぞれのpositionをとります。
座標の演算なので、代入する変数の型はVector3でベクトルとして表されます。
public class HandSender : MonoBehaviour { public Transform Hand; //手の甲 public Transform Thumb; //親指 public Transform Index; //人差し指 public Transform Middle; //中指 public Transform Ring; //薬指 public Transform Pinky; //小指 public Transform Tracker; //トラッカー void Update () { Vector3 HandPos = Hand.position - Tracker.position; Vector3 ThumbPos = Thumb.position - Tracker.position; Vector3 IndexPos = Index.position - Tracker.position; Vector3 MiddlePos = Middle.position - Tracker.position; Vector3 RingPos = Ring.position - Tracker.position; Vector3 PinkyPos = Pinky.position - Tracker.position; } }
実行してみます。
(指先を球形、手の甲を四角形のオブジェクトで表示しています。)
明後日の方向に表示されてしまいました。
どうやら(※)の相対座標が間違っているようです。
Unity上で座標系を確認してみると
右上がVIVEの座標系。真ん中はトラッカーの座標系です。
例えばトラッカーの真上に手を置いたとき、(※)の相対座標では(0, 1, 0)で取得される
ものの、それをトラッカー自体の座標系に適応すると、トラッカーの水平面上にあると認識
されてしまうことがわかると思います。
【成功例】
そこでVIVEの座標系で取得したトラッカーから各指へのベクトルを
トラッカーの座標系に合わせるよう回転させます。
トラッカーから各指へのベクトルx, y, z座標をそれぞれ別に取得します。
(今回は関数translateを作ります。)
public Vector3 translate(Transform t) { Vector3 pos = t.position; Vector3 point = TrackerPos.position; pos.x -= point.x; pos.y -= point.y; pos.z -= point.z; ... }
このベクトルを両座標系のずれに応じて回転させるので、そのずれ(角度)を取得します。
今回は上の座標系図を参考にトラッカー座標系のy軸とVIVE座標系のz軸の角度差を以下の方
法で計算しました。
float angle = Vector3.Angle(TrackerPos.up, Vector3.forward);
ただこのVector3.Angle、成す角のうち小さいほうを取得してしまいます。
例えば実際の角度差が270度のところを90度で返してしまいます。
以下のように外積を用いて-180~180度を表現しました。
if (Vector3.Cross(TrackerPos.up, Vector3.forward).y < 0) angle *= -1;
こうして得られた角度を用いてVIVE座標系y軸中心に回転させます。
pos = Quaternion.Euler(0f, angle, 0f) * pos; return pos;
以上まとめると
public Vector3 translate(Transform t) { Vector3 pos = t.position; Vector3 point = TrackerPos.position; pos.x -= point.x; pos.y -= point.y; pos.z -= point.z; float angle = Vector3.Angle(TrackerPos.up, Vector3.forward); if (Vector3.Cross(TrackerPos.up, Vector3.forward).y < 0) angle *= -1; pos = Quaternion.Euler(0f, angle, 0f) * pos; return pos; }
実行してみると正しく表示されました。
3.なにができそう?
上では実験的に球形、四角形のオブジェクトを座標上に表示させましたがオブジェクトを
スタイリッシュなものにしたり、エフェクトを追加したりすることでプレイヤーにとって
視覚がより先進的なものになるでしょう。
また指先のトラッキングができたので、物体を掴んだり
手の組み方で攻撃、効果を加えたりもできそうです。
さいごに
今回、初めてHi5 VR Gloveを触りましたが指の動きに合わせてモニター内の
オブジェクトが動作する様は快感でした。
より手の込んだ実装も今後試してみたいです。
[…] 以前「【Hi5 VR Glove】指の動きを追ってみる!」で […]