|
ヘッドトラッキング |

| 変数の定義 |
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();
}
|
|
現在のトラッキング情報を取得した後、 頭の「位置」と「角度」から両目の「位置」と「角度」を求め、さらにマトリックスを作成しています 取得できないときは各マトリックスを初期化していますが、実際は前回の値を維持したほうがいいかもしれません |