28 extern int OCULUS_CONNECTED_CB;
29 extern int OCULUS_DISCONNECTED_CB;
31 bool sOculus::isInitialized =
false;
40 mTimeWarpOffset = 0.0;
49 mThread = boost::thread(boost::bind(&sOculus::UpdateThread,
this));
62 isInitialized =
false;
66 bool sOculus::IsConnected()
71 void sOculus::UpdateThread()
76 boost::mutex::scoped_lock l(mMutex);
77 int nbHmd = ovrHmd_Detect();
82 for(
int i = 0; (i < nbHmd) && (mHmd == 0); i++)
83 mHmd = ovrHmd_Create(i);
87 mHmd = ovrHmd_CreateDebug(ovrHmd_DK2);
94 ovrHmd_SetEnabledCaps(mHmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);
96 if ((mHmd->Type == ovrHmd_DK1) || (mHmd->Type == ovrHmd_DKHD))
97 ovrHmd_ConfigureTracking(mHmd, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection, 0);
99 ovrHmd_ConfigureTracking(mHmd, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0);
102 OBJpostEvent(OCULUS_CONNECTED_CB, (
int)
this, 0);
107 if (mConnected && (nbHmd < 1) && !mDebug)
123 ovrHmdType sOculus::GetType()
134 bool sOculus::Connect()
136 boost::mutex::scoped_lock l(mMutex);
140 int nbHmd = ovrHmd_Detect();
143 for(
int i = 0; (i < nbHmd) && (mHmd == 0); i++)
144 mHmd = ovrHmd_Create(i);
149 ovrHmd_SetEnabledCaps(mHmd, ovrHmdCap_LowPersistence | ovrHmdCap_DynamicPrediction);
151 if ((mHmd->Type == ovrHmd_DK1) || (mHmd->Type == ovrHmd_DKHD))
152 ovrHmd_ConfigureTracking(mHmd, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection, 0);
154 ovrHmd_ConfigureTracking(mHmd, ovrTrackingCap_Orientation | ovrTrackingCap_MagYawCorrection | ovrTrackingCap_Position, 0);
158 MMechostr(MSKDEBUG,
"A new Oculus SENSOR has been connected.\n");
159 OBJpostEvent(OCULUS_CONNECTED_CB, (
int)
this, 0);
166 void sOculus::Disconnect()
171 ovrHmd_Destroy(mHmd);
175 OBJpostEvent(OCULUS_DISCONNECTED_CB, (
int)
this, 0);
179 void sOculus::SetLowPersistance(
bool state)
182 ovrHmd_SetEnabledCaps(mHmd, (state) ? ovrHmd_GetEnabledCaps(mHmd) | ovrHmdCap_LowPersistence : ovrHmd_GetEnabledCaps(mHmd) & (~ovrHmdCap_LowPersistence));
185 bool sOculus::GetLowPersistance()
190 if (ovrHmd_GetEnabledCaps(mHmd) & ovrHmdCap_LowPersistence)
196 void sOculus::ResetSensor()
198 boost::mutex::scoped_lock l(mMutex);
200 ovrHmd_RecenterPose(mHmd);
203 Quatf sOculus::GetSensorOrientation()
205 if (!mConnected || !(mTrackingState.StatusFlags & ovrStatus_OrientationTracked))
206 return Quatf(0.0f, 0.0f, 0.0f, 1.0f);
209 Posef pose = mTrackingState.HeadPose.ThePose;
210 return pose.Rotation;
213 Vector3f sOculus::GetSensorYawPitchRoll()
216 return Vector3f(0.0f, 0.0f, 0.0f);
219 Posef pose = mTrackingState.HeadPose.ThePose;
222 Quatf q = pose.Rotation;
226 Matrix4f bodyFrameMatrix(q);
230 q.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&ypr.x, &ypr.y, &ypr.z);
234 Vector3f sOculus::GetSensorAcceleration()
237 return Vector3f(0.0f, 0.0f, 0.0f);
240 return mTrackingState.HeadPose.LinearAcceleration;
243 Vector3f sOculus::GetSensorPosition()
245 if (!mConnected || !(mTrackingState.StatusFlags & ovrStatus_PositionTracked))
246 return Vector3f(0.0f, 0.0f, 0.0f);
248 Posef pose = mTrackingState.HeadPose.ThePose;
251 return pose.Translation;
254 bool sOculus::GetStereoConfigDistortionMesh(ovrEyeType eye, ovrDistortionMesh &mesh)
256 boost::mutex::scoped_lock l(mMutex);
260 ovrEyeRenderDesc eyeRenderDesc = ovrHmd_GetRenderDesc(mHmd, eye, mHmd->DefaultEyeFov[eye]);
261 if (ovrHmd_CreateDistortionMesh(mHmd, eyeRenderDesc.Eye, eyeRenderDesc.Fov, ovrDistortionCap_Chromatic|ovrDistortionCap_TimeWarp|ovrDistortionCap_Vignette, &mesh))
267 bool sOculus::GetProjectionMatrix(ovrEyeType eye,
float nearclip,
float farclip, ovrMatrix4f &mat)
269 boost::mutex::scoped_lock l(mMutex);
273 ovrFovPort fov = mHmd->DefaultEyeFov[eye];
274 mat = ovrMatrix4f_Projection(fov, nearclip, farclip,
true);
278 void sOculus::WaitForFrame()
281 ovr_WaitTillTime(mFrameTiming.TimewarpPointSeconds);
284 void sOculus::SetTimewarpOffset(
double value)
286 mTimeWarpOffset = value;
289 bool sOculus::GetTimeWarpMatrix(ovrEyeType eye, ovrMatrix4f* mat)
292 mat[0].M[0][0] = 1.0f;
293 mat[0].M[0][1] = 0.0f;
294 mat[0].M[0][2] = 0.0f;
295 mat[0].M[0][3] = 0.0f;
296 mat[0].M[1][0] = 0.0f;
297 mat[0].M[1][1] = 1.0f;
298 mat[0].M[1][2] = 0.0f;
299 mat[0].M[1][3] = 0.0f;
300 mat[0].M[2][0] = 0.0f;
301 mat[0].M[2][1] = 0.0f;
302 mat[0].M[2][2] = 1.0f;
303 mat[0].M[2][3] = 0.0f;
304 mat[0].M[3][0] = 0.0f;
305 mat[0].M[3][1] = 0.0f;
306 mat[0].M[3][2] = 0.0f;
307 mat[0].M[3][3] = 1.0f;
309 mat[1].M[0][0] = 1.0f;
310 mat[1].M[0][1] = 0.0f;
311 mat[1].M[0][2] = 0.0f;
312 mat[1].M[0][3] = 0.0f;
313 mat[1].M[1][0] = 0.0f;
314 mat[1].M[1][1] = 1.0f;
315 mat[1].M[1][2] = 0.0f;
316 mat[1].M[1][3] = 0.0f;
317 mat[1].M[2][0] = 0.0f;
318 mat[1].M[2][1] = 0.0f;
319 mat[1].M[2][2] = 1.0f;
320 mat[1].M[2][3] = 0.0f;
321 mat[1].M[3][0] = 0.0f;
322 mat[1].M[3][1] = 0.0f;
323 mat[1].M[3][2] = 0.0f;
324 mat[1].M[3][3] = 1.0f;
326 if (!mHmd || !mUpdated)
329 ovrHmd_GetEyeTimewarpMatricesDebug(mHmd, eye, mEyepos[eye], mat, mTimeWarpOffset);
334 Sizei sOculus::GetStereoConfigFovTextureSize(ovrEyeType eye)
336 boost::mutex::scoped_lock l(mMutex);
338 return Sizei(512, 512);
340 return ovrHmd_GetFovTextureSize(mHmd, eye, mHmd->DefaultEyeFov[eye], 1.0f);
343 bool sOculus::GetStereoConfigUvScaleOffset(ovrEyeType eye, Sizei textSize, Vector2f &scale, Vector2f &offset)
345 boost::mutex::scoped_lock l(mMutex);
349 ovrEyeRenderDesc eyeRenderDesc = ovrHmd_GetRenderDesc(mHmd, eye, mHmd->DefaultEyeFov[eye]);
354 viewport.Size.w = textSize.w;
355 viewport.Size.h = textSize.h;
357 ovrVector2f UVScaleOffset[2];
358 ovrHmd_GetRenderScaleAndOffset(eyeRenderDesc.Fov, textSize, viewport, UVScaleOffset);
359 scale = UVScaleOffset[0];
360 offset = UVScaleOffset[1];
364 bool sOculus::GetWindowPosAndSize(Vector2i &pos, Sizei &size,
int &monitorIndex)
366 boost::mutex::scoped_lock l(mMutex);
371 pos = Vector2i(-1920, 0);
373 pos = mHmd->WindowsPos;
374 size = mHmd->Resolution;
375 monitorIndex = (mHmd->DisplayId < 0) ? 1 : mHmd->DisplayId;
379 float sOculus::GetStereoConfigAspect()
381 boost::mutex::scoped_lock l(mMutex);
384 ovrFovPort fovLeft = mHmd->DefaultEyeFov[ovrEye_Left];
385 ovrFovPort fovRight = mHmd->DefaultEyeFov[ovrEye_Right];
387 float combinedTanHalfFovHorizontal = std::max(fovLeft.LeftTan, fovLeft.RightTan);
388 float combinedTanHalfFovVertical = std::max(fovLeft.UpTan, fovLeft.DownTan);
389 return combinedTanHalfFovHorizontal / combinedTanHalfFovVertical;
395 float sOculus::GetStereoConfigFovY()
397 boost::mutex::scoped_lock l(mMutex);
400 ovrFovPort fovLeft = mHmd->DefaultEyeFov[ovrEye_Left];
401 ovrFovPort fovRight = mHmd->DefaultEyeFov[ovrEye_Right];
403 return (atanf(fovLeft.UpTan) + atanf(fovLeft.DownTan) + atanf(fovRight.UpTan) + atanf(fovRight.DownTan)) * 0.5f;
409 float sOculus::GetStereoIPD()
411 boost::mutex::scoped_lock l(mMutex);
414 return ovrHmd_GetFloat(mHmd, OVR_KEY_IPD, 0.064f);
420 bool sOculus::UpdateStart()
424 mFrameTiming = ovrHmd_BeginFrameTiming(mHmd, 0);
427 ovrEyeRenderDesc eyeRenderDesc[2] = {ovrHmd_GetRenderDesc(mHmd, ovrEye_Left, mHmd->DefaultEyeFov[ovrEye_Left]), ovrHmd_GetRenderDesc(mHmd, ovrEye_Right, mHmd->DefaultEyeFov[ovrEye_Right])};
428 ovrVector3f useHmdToEyeViewOffset[2] = {eyeRenderDesc[0].HmdToEyeViewOffset, eyeRenderDesc[1].HmdToEyeViewOffset};
433 ovrHmd_GetEyePoses(mHmd, 0, useHmdToEyeViewOffset, mEyepos, &mTrackingState);
441 void sOculus::UpdateEnd()
443 if (mHmd && mUpdated)
445 ovrHmd_EndFrameTiming(mHmd);