ヘッドトラッキング |
変数の定義 |
XMMATRIX m_VREyeMtx[2]; XMMATRIX m_VRHeadMtx; |
ovrPosef から マトリックスへの変換関数 |
void CalcPoseToMtx( XMMATRIX *pMtx, const ovrPosef *pPose ) { const ovrQuatf *pQt = &pPose->Orientation; const ovrVector3f *pPos = &pPose->Position; // union { // XMVECTOR が扱いにくいので共用体を定義 // XMVECTOR xv; struct { float x,y,z,w; }; } xqt, xpos; xqt.x = +pQt->x; xqt.y = +pQt->y; xqt.z = -pQt->z; xqt.w = +pQt->w; // z 軸のみ反転 // XMMATRIX xmtx = XMMatrixRotationQuaternion( xqt.xv ); // xpos.x = -pPos->x; xpos.y = -pPos->y; xpos.z = +pPos->z; // z 軸のみ反転 // xpos.w = +1.0f; xmtx.r[3] = XMVector3TransformCoord( xpos.xv, xmtx ); *pMtx = xmtx; } |
3次元座標であらわされる「位置」とクォータニオンであらわされる「角度」からマトリックスを作成します SDK が返す情報は右手座標系で -Z が前になっているので、この例では左手座標系に変換するために反転しています 角軸の符号はレンダリングシステム(もしくはアプリ側の実装)に依存するので、自分の環境に合わせてカスタマイズする必要があります |
トラッキング情報の取得 |
// 現在のトラッキング情報を取得 // ovrTrackingState ts = ovr_GetTrackingState( m_OVRSessionId, ovr_GetTimeInSeconds(), ovrTrue ); if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked)) { // headPose から両目の位置と角度を取得 // ovr_CalcEyePoses( ts.HeadPose.ThePose, m_hmdToEyeViewOffset, m_OVRLayer.RenderPose ); // 位置と角度からマトリックスを作成 // for(int eye=0;eye<2;eye++) { CalcPoseToMtx( &m_VREyeMtx[eye], &m_OVRLayer.RenderPose[eye] ); } CnvPoseToMtx( &m_VRHeadMtx, &ts.HeadPose.ThePose ); } else { // トラッキングに失敗したら正規直行マトリックスで初期化 // for(int eye=0;eye<2;eye++) { m_VREyeMtx[eye] = XMMatrixIdentity(); } m_VRHeadMtx = XMMatrixIdentity(); } |
現在のトラッキング情報を取得した後、 頭の「位置」と「角度」から両目の「位置」と「角度」を求め、さらにマトリックスを作成しています 取得できないときは各マトリックスを初期化していますが、実際は前回の値を維持したほうがいいかもしれません |