ヘッドトラッキング


各種センサーを使ってユーザーが頭にかぶったヘッドセットの位置と角度を特定しますが、実際の計算は SDK 内部で行われるため、アプリ側で必要なのは結果を取得する処理だけです。


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


back