前置き
こんにちはTOKIです
プログラムの原理的な部分について解説します
まだ読んでない人は前回を読んでからの方が良いと思います
今回の話は前提としてFinal IKを用いた場合の話なのですが
もしかしたら別のIKシステムやまったく別の問題にも使えるかも...?
御託はここまで
原理
そもそもSteamVR(VIVEやValve)のトラッキング座標はどう処理されている?
ベースステーションを用いたトラッキング方法は
HTC Vive Lighthouse Chaperon tracking system Explained
に紹介されているように同期フラッシュと左右,上下方向の光の走査の受信タイミングで行われており
ベースステーションに対する角度から位置を推定しています
Unity上でCameraRigを配置するとCameraRigのScaleに合わせてHMDやController,TrackerがCameraRig原点に対する相対位置で配置されます
なのでCamera (head)(Camera (eye)の親階層)やController (right),Controller (left)の親階層のScaleが変更されるとCameraRig原点からの相対距離が変化します
こんな感じ |
何が問題になるか
Final IKはあくまでターゲットに合わせてアバタを動かすものなので
上記のことがややこしい問題を起こします
まずやりたいこととして自分の腕を伸ばしきるタイミングと
アバタの腕が伸びきるタイミングを一致させることなのですが
アバタは身長と両手を広げた時の幅が一致しないことがあり
身長のスケールに合わせても腕を横にした時に
アバタの腕が伸びきらない(もしくはその逆)という事が生じます
また肩幅の比率も多々違うので腕を前にした時にも
アバタの腕が伸びきらない(もしk(ry)という事が生じます
じゃあCameraRigのScaleに各軸別の値を入れよう
という事をしようとしても
- 頭を傾けた際にHMDのIPD(ICD, 詳しくは→ HMDの瞳孔間距離不整合による世界変形)が変化してしまう
- 身体の向きを変えた時に破綻する
といった問題が生じます
1つ目の問題についてはCameraRigのScaleをいじらずに
Camera (head)とController (right OR left)に
それぞれ別の新しい親階層を作り
そこにScaleを入れればいいと思うわけですが
そうすると原点からの相対距離にScaleがかけられるので
HMDとControllerの間にズレが生じていきます
(しかも原点から離れるとズレが大きくなる)
こんな感じで... |
2つ目の問題に対してはこのままではどうしようもありません
解決法
上記の問題はControllerが
原点に対する距離で計算されるのが原因であるため
Final IKのターゲットとなる位置を
HMDに対する相対距離で計算できるようにすれば解決します
しかし実際にはControllerが止まっていて
HMDが動くこともあるので
アバタのUpperChestを基準に計算します
(ただしY軸方向は地面を基準)
計算自体は下図のように座標変換をおこなった後に
Scale変換をおこない元の座標系に戻すだけです
この時身体の前,横方向で
かけるScaleを変えたいので回転もおこないます
またUnityは左手座標系なのでそこだけ注意します
0 件のコメント:
コメントを投稿