openVRProvider.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. #include "platform/input/openVR/openVRProvider.h"
  2. #include "platform/platformInput.h"
  3. #include "core/module.h"
  4. #include "console/engineAPI.h"
  5. #include "T3D/gameBase/gameConnection.h"
  6. #include "gui/core/guiCanvas.h"
  7. #include "postFx/postEffectCommon.h"
  8. #include "gfx/D3D11/gfxD3D11Device.h"
  9. #include "gfx/D3D11/gfxD3D11TextureObject.h"
  10. #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
  11. #include "gfx/gfxStringEnumTranslate.h"
  12. /*
  13. #include "gfx/gl/gfxGLDevice.h"
  14. #include "gfx/gl/gfxGLTextureObject.h"
  15. #include "gfx/gl/gfxGLEnumTranslate.h"
  16. */
  17. #include "platform/input/oculusVR/oculusVRUtil.h"
  18. U32 OpenVRProvider::OVR_SENSORROT[vr::k_unMaxTrackedDeviceCount] = { 0 };
  19. U32 OpenVRProvider::OVR_SENSORROTANG[vr::k_unMaxTrackedDeviceCount] = { 0 };
  20. U32 OpenVRProvider::OVR_SENSORVELOCITY[vr::k_unMaxTrackedDeviceCount] = { 0 };
  21. U32 OpenVRProvider::OVR_SENSORANGVEL[vr::k_unMaxTrackedDeviceCount] = { 0 };
  22. U32 OpenVRProvider::OVR_SENSORMAGNETOMETER[vr::k_unMaxTrackedDeviceCount] = { 0 };
  23. U32 OpenVRProvider::OVR_SENSORPOSITION[vr::k_unMaxTrackedDeviceCount] = { 0 };
  24. U32 OpenVRProvider::OVR_BUTTONPRESSED[vr::k_unMaxTrackedDeviceCount];
  25. U32 OpenVRProvider::OVR_BUTTONTOUCHED[vr::k_unMaxTrackedDeviceCount];
  26. U32 OpenVRProvider::OVR_AXISNONE[vr::k_unMaxTrackedDeviceCount] = { 0 };
  27. U32 OpenVRProvider::OVR_AXISTRACKPAD[vr::k_unMaxTrackedDeviceCount] = { 0 };
  28. U32 OpenVRProvider::OVR_AXISJOYSTICK[vr::k_unMaxTrackedDeviceCount] = { 0 };
  29. U32 OpenVRProvider::OVR_AXISTRIGGER[vr::k_unMaxTrackedDeviceCount] = { 0 };
  30. static String GetTrackedDeviceString(vr::IVRSystem *pHmd, vr::TrackedDeviceIndex_t unDevice, vr::TrackedDeviceProperty prop, vr::TrackedPropertyError *peError = NULL)
  31. {
  32. uint32_t unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty(unDevice, prop, NULL, 0, peError);
  33. if (unRequiredBufferLen == 0)
  34. return "";
  35. char *pchBuffer = new char[unRequiredBufferLen];
  36. unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty(unDevice, prop, pchBuffer, unRequiredBufferLen, peError);
  37. String sResult = pchBuffer;
  38. delete[] pchBuffer;
  39. return sResult;
  40. }
  41. static MatrixF ConvertSteamVRAffineMatrixToMatrixFPlain(const vr::HmdMatrix34_t &mat)
  42. {
  43. MatrixF outMat(1);
  44. outMat.setColumn(0, Point4F(mat.m[0][0], mat.m[1][0], mat.m[2][0], 0.0));
  45. outMat.setColumn(1, Point4F(mat.m[0][1], mat.m[1][1], mat.m[2][1], 0.0));
  46. outMat.setColumn(2, Point4F(mat.m[0][2], mat.m[1][2], mat.m[2][2], 0.0));
  47. outMat.setColumn(3, Point4F(mat.m[0][3], mat.m[1][3], mat.m[2][3], 1.0f)); // pos
  48. return outMat;
  49. }
  50. MODULE_BEGIN(OpenVRProvider)
  51. MODULE_INIT_AFTER(InputEventManager)
  52. MODULE_SHUTDOWN_BEFORE(InputEventManager)
  53. MODULE_INIT
  54. {
  55. OpenVRProvider::staticInit();
  56. ManagedSingleton< OpenVRProvider >::createSingleton();
  57. }
  58. MODULE_SHUTDOWN
  59. {
  60. ManagedSingleton< OpenVRProvider >::deleteSingleton();
  61. }
  62. MODULE_END;
  63. bool OpenVRRenderState::setupRenderTargets(U32 mode)
  64. {
  65. if (!mHMD)
  66. return false;
  67. U32 sizeX, sizeY;
  68. Point2I newRTSize;
  69. mHMD->GetRecommendedRenderTargetSize(&sizeX, &sizeY);
  70. mEyeViewport[0] = RectI(Point2I(0, 0), Point2I(sizeX, sizeY));
  71. mEyeViewport[1] = RectI(Point2I(0, 0), Point2I(sizeX, sizeY));
  72. newRTSize.x = sizeX;
  73. newRTSize.y = sizeY;
  74. GFXTexHandle stereoTexture;
  75. stereoTexture.set(newRTSize.x, newRTSize.y, GFXFormatR8G8B8A8, &VRTextureProfile, "OpenVR Stereo RT Color");
  76. mStereoRenderTextures[0] = mStereoRenderTextures[1] = stereoTexture;
  77. GFXTexHandle stereoDepthTexture;
  78. stereoDepthTexture.set(newRTSize.x, newRTSize.y, GFXFormatD24S8, &VRDepthProfile, "OpenVR Depth");
  79. mStereoDepthTextures[0] = mStereoDepthTextures[1] = stereoDepthTexture;
  80. mStereoRT = GFX->allocRenderToTextureTarget();
  81. mStereoRT->attachTexture(GFXTextureTarget::Color0, stereoTexture);
  82. mStereoRT->attachTexture(GFXTextureTarget::DepthStencil, stereoDepthTexture);
  83. mEyeRT[0] = mEyeRT[1] = mStereoRT;
  84. return true;
  85. }
  86. void OpenVRRenderState::setupDistortion()
  87. {
  88. if (!mHMD)
  89. return;
  90. U16 m_iLensGridSegmentCountH = 43;
  91. U16 m_iLensGridSegmentCountV = 43;
  92. float w = (float)(1.0 / float(m_iLensGridSegmentCountH - 1));
  93. float h = (float)(1.0 / float(m_iLensGridSegmentCountV - 1));
  94. float u, v = 0;
  95. Vector<GFXVertexPTTT> vVerts(0);
  96. GFXVertexPTTT *vert;
  97. vVerts.reserve((m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2);
  98. mDistortionVerts.set(GFX, (m_iLensGridSegmentCountV * m_iLensGridSegmentCountH) * 2, GFXBufferTypeStatic);
  99. vert = mDistortionVerts.lock();
  100. //left eye distortion verts
  101. float Xoffset = -1;
  102. for (int y = 0; y < m_iLensGridSegmentCountV; y++)
  103. {
  104. for (int x = 0; x < m_iLensGridSegmentCountH; x++)
  105. {
  106. u = x*w; v = 1 - y*h;
  107. vert->point = Point3F(Xoffset + u, -1 + 2 * y*h, 0.0f);
  108. vr::DistortionCoordinates_t dc0 = mHMD->ComputeDistortion(vr::Eye_Left, u, v);
  109. vert->texCoord1 = Point2F(dc0.rfRed[0], 1 - dc0.rfRed[1]); // r
  110. vert->texCoord2 = Point2F(dc0.rfGreen[0], 1 - dc0.rfGreen[1]); // g
  111. vert->texCoord3 = Point2F(dc0.rfBlue[0], 1 - dc0.rfBlue[1]); // b
  112. vert++;
  113. }
  114. }
  115. //right eye distortion verts
  116. Xoffset = 0;
  117. for (int y = 0; y < m_iLensGridSegmentCountV; y++)
  118. {
  119. for (int x = 0; x < m_iLensGridSegmentCountH; x++)
  120. {
  121. u = x*w; v = 1 - y*h;
  122. vert->point = Point3F(Xoffset + u, -1 + 2 * y*h, 0.0f);
  123. vr::DistortionCoordinates_t dc0 = mHMD->ComputeDistortion(vr::Eye_Right, u, v);
  124. vert->texCoord1 = Point2F(dc0.rfRed[0], 1 - dc0.rfRed[1]);
  125. vert->texCoord2 = Point2F(dc0.rfGreen[0], 1 - dc0.rfGreen[1]);
  126. vert->texCoord3 = Point2F(dc0.rfBlue[0], 1 - dc0.rfBlue[1]);
  127. vert++;
  128. }
  129. }
  130. mDistortionVerts.unlock();
  131. mDistortionInds.set(GFX, m_iLensGridSegmentCountV * m_iLensGridSegmentCountH * 6 * 2, 0, GFXBufferTypeStatic);
  132. GFXPrimitive *prim;
  133. U16 *index;
  134. mDistortionInds.lock(&index, &prim);
  135. U16 a, b, c, d;
  136. U16 offset = 0;
  137. for (U16 y = 0; y < m_iLensGridSegmentCountV - 1; y++)
  138. {
  139. for (U16 x = 0; x < m_iLensGridSegmentCountH - 1; x++)
  140. {
  141. a = m_iLensGridSegmentCountH*y + x + offset;
  142. b = m_iLensGridSegmentCountH*y + x + 1 + offset;
  143. c = (y + 1)*m_iLensGridSegmentCountH + x + 1 + offset;
  144. d = (y + 1)*m_iLensGridSegmentCountH + x + offset;
  145. *index++ = a;
  146. *index++ = b;
  147. *index++ = c;
  148. *index++ = a;
  149. *index++ = c;
  150. *index++ = d;
  151. }
  152. }
  153. offset = (m_iLensGridSegmentCountH)*(m_iLensGridSegmentCountV);
  154. for (U16 y = 0; y < m_iLensGridSegmentCountV - 1; y++)
  155. {
  156. for (U16 x = 0; x < m_iLensGridSegmentCountH - 1; x++)
  157. {
  158. a = m_iLensGridSegmentCountH*y + x + offset;
  159. b = m_iLensGridSegmentCountH*y + x + 1 + offset;
  160. c = (y + 1)*m_iLensGridSegmentCountH + x + 1 + offset;
  161. d = (y + 1)*m_iLensGridSegmentCountH + x + offset;
  162. *index++ = a;
  163. *index++ = b;
  164. *index++ = c;
  165. *index++ = a;
  166. *index++ = c;
  167. *index++ = d;
  168. }
  169. }
  170. mDistortionInds.unlock();
  171. }
  172. void OpenVRRenderState::renderDistortion(U32 eye)
  173. {
  174. // Updates distortion for an eye (this should only be the case for backend APIS where image should be predistorted)
  175. /*
  176. glDisable(GL_DEPTH_TEST);
  177. glViewport( 0, 0, m_nWindowWidth, m_nWindowHeight );
  178. glBindVertexArray( m_unLensVAO );
  179. glUseProgram( m_unLensProgramID );
  180. //render left lens (first half of index array )
  181. glBindTexture(GL_TEXTURE_2D, leftEyeDesc.m_nResolveTextureId );
  182. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  183. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  184. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  185. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
  186. glDrawElements( GL_TRIANGLES, m_uiIndexSize/2, GL_UNSIGNED_SHORT, 0 );
  187. //render right lens (second half of index array )
  188. glBindTexture(GL_TEXTURE_2D, rightEyeDesc.m_nResolveTextureId );
  189. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
  190. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
  191. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
  192. glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
  193. glDrawElements( GL_TRIANGLES, m_uiIndexSize/2, GL_UNSIGNED_SHORT, (const void *)(m_uiIndexSize) );
  194. glBindVertexArray( 0 );
  195. glUseProgram( 0 );
  196. */
  197. }
  198. void OpenVRRenderState::renderPreview()
  199. {
  200. }
  201. void OpenVRRenderState::reset(vr::IVRSystem* hmd)
  202. {
  203. mHMD = hmd;
  204. mStereoRT = NULL;
  205. mEyeRT[0] = mEyeRT[1] = NULL;
  206. mStereoRenderTextures[0] = mStereoRenderTextures[1] = NULL;
  207. mStereoDepthTextures[0] = mStereoDepthTextures[1] = NULL;
  208. mDistortionVerts = NULL;
  209. mDistortionInds = NULL;
  210. if (!mHMD)
  211. return;
  212. vr::HmdMatrix34_t mat = mHMD->GetEyeToHeadTransform(vr::Eye_Left);
  213. mEyePose[0] = ConvertSteamVRAffineMatrixToMatrixFPlain(mat);
  214. mEyePose[0].inverse();
  215. mat = mHMD->GetEyeToHeadTransform(vr::Eye_Right);
  216. mEyePose[1] = ConvertSteamVRAffineMatrixToMatrixFPlain(mat);
  217. mEyePose[1].inverse();
  218. mHMD->GetProjectionRaw(vr::Eye_Left, &mEyeFov[0].leftTan, &mEyeFov[0].rightTan, &mEyeFov[0].upTan, &mEyeFov[0].downTan);
  219. mHMD->GetProjectionRaw(vr::Eye_Right, &mEyeFov[1].leftTan, &mEyeFov[1].rightTan, &mEyeFov[1].upTan, &mEyeFov[1].downTan);
  220. mEyeFov[0].upTan = -mEyeFov[0].upTan;
  221. mEyeFov[0].leftTan = -mEyeFov[0].leftTan;
  222. mEyeFov[1].upTan = -mEyeFov[1].upTan;
  223. mEyeFov[1].leftTan = -mEyeFov[1].leftTan;
  224. }
  225. OpenVRProvider::OpenVRProvider() :
  226. mHMD(NULL),
  227. mRenderModels(NULL),
  228. mDrawCanvas(NULL),
  229. mGameConnection(NULL)
  230. {
  231. dStrcpy(mName, "openvr");
  232. mDeviceType = INPUTMGR->getNextDeviceType();
  233. buildInputCodeTable();
  234. GFXDevice::getDeviceEventSignal().notify(this, &OpenVRProvider::_handleDeviceEvent);
  235. INPUTMGR->registerDevice(this);
  236. }
  237. OpenVRProvider::~OpenVRProvider()
  238. {
  239. }
  240. void OpenVRProvider::staticInit()
  241. {
  242. // TODO: Add console vars
  243. }
  244. bool OpenVRProvider::enable()
  245. {
  246. disable();
  247. // Load openvr runtime
  248. vr::EVRInitError eError = vr::VRInitError_None;
  249. mHMD = vr::VR_Init(&eError, vr::VRApplication_Scene);
  250. dMemset(mDeviceClassChar, '\0', sizeof(mDeviceClassChar));
  251. if (eError != vr::VRInitError_None)
  252. {
  253. mHMD = NULL;
  254. char buf[1024];
  255. sprintf_s(buf, sizeof(buf), "Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError));
  256. Con::printf(buf);
  257. return false;
  258. }
  259. mRenderModels = (vr::IVRRenderModels *)vr::VR_GetGenericInterface(vr::IVRRenderModels_Version, &eError);
  260. if (!mRenderModels)
  261. {
  262. mHMD = NULL;
  263. vr::VR_Shutdown();
  264. char buf[1024];
  265. sprintf_s(buf, sizeof(buf), "Unable to get render model interface: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError));
  266. Con::printf(buf);
  267. return false;
  268. }
  269. mDriver = GetTrackedDeviceString(mHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_TrackingSystemName_String);
  270. mDisplay = GetTrackedDeviceString(mHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SerialNumber_String);
  271. mHMDRenderState.reset(mHMD);
  272. mHMD->ResetSeatedZeroPose();
  273. dMemset(mPreviousInputTrackedDevicePose, '\0', sizeof(mPreviousInputTrackedDevicePose));
  274. mEnabled = true;
  275. return true;
  276. }
  277. bool OpenVRProvider::disable()
  278. {
  279. if (mHMD)
  280. {
  281. mHMD = NULL;
  282. mRenderModels = NULL;
  283. mHMDRenderState.reset(NULL);
  284. vr::VR_Shutdown();
  285. }
  286. mEnabled = false;
  287. return true;
  288. }
  289. void OpenVRProvider::buildInputCodeTable()
  290. {
  291. // Obtain all of the device codes
  292. for (U32 i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i)
  293. {
  294. OVR_SENSORROT[i] = INPUTMGR->getNextDeviceCode();
  295. OVR_SENSORROTANG[i] = INPUTMGR->getNextDeviceCode();
  296. OVR_SENSORVELOCITY[i] = INPUTMGR->getNextDeviceCode();
  297. OVR_SENSORANGVEL[i] = INPUTMGR->getNextDeviceCode();
  298. OVR_SENSORMAGNETOMETER[i] = INPUTMGR->getNextDeviceCode();
  299. OVR_SENSORPOSITION[i] = INPUTMGR->getNextDeviceCode();
  300. OVR_BUTTONPRESSED[i] = INPUTMGR->getNextDeviceCode();
  301. OVR_BUTTONTOUCHED[i] = INPUTMGR->getNextDeviceCode();
  302. OVR_AXISNONE[i] = INPUTMGR->getNextDeviceCode();
  303. OVR_AXISTRACKPAD[i] = INPUTMGR->getNextDeviceCode();
  304. OVR_AXISJOYSTICK[i] = INPUTMGR->getNextDeviceCode();
  305. OVR_AXISTRIGGER[i] = INPUTMGR->getNextDeviceCode();
  306. }
  307. // Build out the virtual map
  308. char buffer[64];
  309. for (U32 i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i)
  310. {
  311. dSprintf(buffer, 64, "opvr_sensorrot%d", i);
  312. INPUTMGR->addVirtualMap(buffer, SI_ROT, OVR_SENSORROT[i]);
  313. dSprintf(buffer, 64, "opvr_sensorrotang%d", i);
  314. INPUTMGR->addVirtualMap(buffer, SI_POS, OVR_SENSORROTANG[i]);
  315. dSprintf(buffer, 64, "opvr_sensorvelocity%d", i);
  316. INPUTMGR->addVirtualMap(buffer, SI_POS, OVR_SENSORVELOCITY[i]);
  317. dSprintf(buffer, 64, "opvr_sensorangvel%d", i);
  318. INPUTMGR->addVirtualMap(buffer, SI_POS, OVR_SENSORANGVEL[i]);
  319. dSprintf(buffer, 64, "opvr_sensormagnetometer%d", i);
  320. INPUTMGR->addVirtualMap(buffer, SI_POS, OVR_SENSORMAGNETOMETER[i]);
  321. dSprintf(buffer, 64, "opvr_sensorpos%d", i);
  322. INPUTMGR->addVirtualMap(buffer, SI_POS, OVR_SENSORPOSITION[i]);
  323. dSprintf(buffer, 64, "opvr_buttonpressed%d", i);
  324. INPUTMGR->addVirtualMap(buffer, SI_INT, OVR_BUTTONPRESSED[i]);
  325. dSprintf(buffer, 64, "opvr_buttontouched%d", i);
  326. INPUTMGR->addVirtualMap(buffer, SI_INT, OVR_BUTTONTOUCHED[i]);
  327. dSprintf(buffer, 64, "opvr_axis_none%d", i);
  328. INPUTMGR->addVirtualMap(buffer, SI_POS, OVR_AXISNONE[i]);
  329. dSprintf(buffer, 64, "opvr_axis_trackpad%d", i);
  330. INPUTMGR->addVirtualMap(buffer, SI_POS, OVR_AXISTRACKPAD[i]);
  331. dSprintf(buffer, 64, "opvr_axis_joystick%d", i);
  332. INPUTMGR->addVirtualMap(buffer, SI_POS, OVR_AXISJOYSTICK[i]);
  333. dSprintf(buffer, 64, "opvr_axis_trigger%d", i);
  334. INPUTMGR->addVirtualMap(buffer, SI_INT, OVR_AXISTRIGGER[i]);
  335. }
  336. }
  337. bool OpenVRProvider::process()
  338. {
  339. if (!mHMD)
  340. return true;
  341. // Process SteamVR events
  342. vr::VREvent_t event;
  343. while (mHMD->PollNextEvent(&event, sizeof(event)))
  344. {
  345. processVREvent(event);
  346. }
  347. // Process SteamVR controller state
  348. for (vr::TrackedDeviceIndex_t unDevice = 0; unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++)
  349. {
  350. vr::VRControllerState_t state;
  351. if (mHMD->GetControllerState(unDevice, &state))
  352. {
  353. // TODO
  354. }
  355. }
  356. // Update input poses
  357. updateTrackedPoses();
  358. submitInputChanges();
  359. return true;
  360. }
  361. bool OpenVRProvider::providesFrameEyePose() const
  362. {
  363. return mHMD != NULL;
  364. }
  365. inline Point3F OpenVRVecToTorqueVec(vr::HmdVector3_t vec)
  366. {
  367. return Point3F(-vec.v[0], vec.v[2], -vec.v[1]);
  368. }
  369. void OpenVRTransformToRotPos(MatrixF mat, QuatF &outRot, Point3F &outPos)
  370. {
  371. // Directly set the rotation and position from the eye transforms
  372. MatrixF torqueMat(1);
  373. F32 inRotMat[4][4];
  374. Point4F col0; mat.getColumn(0, &col0);
  375. Point4F col1; mat.getColumn(1, &col1);
  376. Point4F col2; mat.getColumn(2, &col2);
  377. Point4F col3; mat.getColumn(3, &col3);
  378. inRotMat[0][0] = col0.x;
  379. inRotMat[0][1] = col0.y;
  380. inRotMat[0][2] = col0.z;
  381. inRotMat[0][3] = col0.w;
  382. inRotMat[1][0] = col1.x;
  383. inRotMat[1][1] = col1.y;
  384. inRotMat[1][2] = col1.z;
  385. inRotMat[1][3] = col1.w;
  386. inRotMat[2][0] = col2.x;
  387. inRotMat[2][1] = col2.y;
  388. inRotMat[2][2] = col2.z;
  389. inRotMat[2][3] = col2.w;
  390. inRotMat[3][0] = col3.x;
  391. inRotMat[3][1] = col3.y;
  392. inRotMat[3][2] = col3.z;
  393. inRotMat[3][3] = col3.w;
  394. OculusVRUtil::convertRotation(inRotMat, torqueMat);
  395. Point3F pos = torqueMat.getPosition();
  396. outRot = QuatF(torqueMat);
  397. outPos = Point3F(-pos.x, pos.z, -pos.y);
  398. }
  399. void OpenVRProvider::getFrameEyePose(IDevicePose *pose, U32 eye) const
  400. {
  401. AssertFatal(eye >= 0 && eye < 2, "Out of bounds eye");
  402. MatrixF mat = mHMDRenderState.mHMDPose * mHMDRenderState.mEyePose[eye];
  403. OpenVRTransformToRotPos(mat, pose->orientation, pose->position);
  404. pose->velocity = Point3F(0);
  405. pose->angularVelocity = Point3F(0);
  406. }
  407. bool OpenVRProvider::providesEyeOffsets() const
  408. {
  409. return mHMD != NULL;
  410. }
  411. /// Returns eye offset not taking into account any position tracking info
  412. void OpenVRProvider::getEyeOffsets(Point3F *dest) const
  413. {
  414. dest[0] = mHMDRenderState.mEyePose[0].getPosition();
  415. dest[1] = mHMDRenderState.mEyePose[1].getPosition();
  416. }
  417. bool OpenVRProvider::providesFovPorts() const
  418. {
  419. return mHMD != NULL;
  420. }
  421. void OpenVRProvider::getFovPorts(FovPort *out) const
  422. {
  423. dMemcpy(out, mHMDRenderState.mEyeFov, sizeof(mHMDRenderState.mEyeFov));
  424. }
  425. bool OpenVRProvider::providesProjectionOffset() const
  426. {
  427. return mHMD != NULL;
  428. }
  429. const Point2F& OpenVRProvider::getProjectionOffset() const
  430. {
  431. return Point2F(0, 0);
  432. }
  433. void OpenVRProvider::getStereoViewports(RectI *out) const
  434. {
  435. out[0] = mHMDRenderState.mEyeViewport[0];
  436. out[1] = mHMDRenderState.mEyeViewport[1];
  437. }
  438. void OpenVRProvider::getStereoTargets(GFXTextureTarget **out) const
  439. {
  440. out[0] = mHMDRenderState.mEyeRT[0];
  441. out[1] = mHMDRenderState.mEyeRT[1];
  442. }
  443. void OpenVRProvider::setDrawCanvas(GuiCanvas *canvas)
  444. {
  445. vr::EVRInitError peError = vr::VRInitError_None;
  446. if (!vr::VRCompositor())
  447. {
  448. printf("Compositor initialization failed. See log file for details\n");
  449. return;
  450. }
  451. if (mDrawCanvas != canvas || mHMDRenderState.mHMD == NULL)
  452. {
  453. mHMDRenderState.setupRenderTargets(0);
  454. }
  455. mDrawCanvas = canvas;
  456. }
  457. void OpenVRProvider::setCurrentConnection(GameConnection *connection)
  458. {
  459. mGameConnection = connection;
  460. }
  461. GameConnection* OpenVRProvider::getCurrentConnection()
  462. {
  463. return mGameConnection;
  464. }
  465. GFXTexHandle OpenVRProvider::getPreviewTexture()
  466. {
  467. return mHMDRenderState.mStereoRenderTextures[0]; // TODO: render distortion preview
  468. }
  469. void OpenVRProvider::onStartFrame()
  470. {
  471. if (!mHMD)
  472. return;
  473. }
  474. void OpenVRProvider::onEndFrame()
  475. {
  476. if (!mHMD)
  477. return;
  478. }
  479. void OpenVRProvider::onEyeRendered(U32 index)
  480. {
  481. if (!mHMD)
  482. return;
  483. if (GFX->getAdapterType() == Direct3D11)
  484. {
  485. vr::Texture_t eyeTexture = { (void*)static_cast<GFXD3D11TextureObject*>(mHMDRenderState.mStereoRenderTextures[index].getPointer())->get2DTex(), vr::API_DirectX, vr::ColorSpace_Gamma };
  486. vr::VRCompositor()->Submit((vr::EVREye)(vr::Eye_Left + index), &eyeTexture);
  487. }
  488. else if (GFX->getAdapterType() == OpenGL)
  489. {/*
  490. vr::Texture_t eyeTexture = { (void*)static_cast<GFXGLTextureObject*>(mHMDRenderState.mStereoRenderTextures[index].getPointer())->getHandle(), vr::API_OpenGL, vr::ColorSpace_Gamma };
  491. vr::VRCompositor()->Submit((vr::EVREye)(vr::Eye_Left + index), &eyeTexture);*/
  492. }
  493. }
  494. bool OpenVRProvider::_handleDeviceEvent(GFXDevice::GFXDeviceEventType evt)
  495. {
  496. if (!ManagedSingleton<OpenVRProvider>::instanceOrNull())
  497. {
  498. return true;
  499. }
  500. switch (evt)
  501. {
  502. case GFXDevice::deStartOfFrame:
  503. // Start of frame
  504. onStartFrame();
  505. break;
  506. case GFXDevice::dePostFrame:
  507. // End of frame
  508. onEndFrame();
  509. break;
  510. case GFXDevice::deDestroy:
  511. // Need to reinit rendering
  512. break;
  513. case GFXDevice::deLeftStereoFrameRendered:
  514. //
  515. onEyeRendered(0);
  516. break;
  517. case GFXDevice::deRightStereoFrameRendered:
  518. //
  519. onEyeRendered(1);
  520. break;
  521. default:
  522. break;
  523. }
  524. return true;
  525. }
  526. void OpenVRProvider::processVREvent(const vr::VREvent_t & event)
  527. {
  528. switch (event.eventType)
  529. {
  530. case vr::VREvent_TrackedDeviceActivated:
  531. {
  532. // Setup render model
  533. }
  534. break;
  535. case vr::VREvent_TrackedDeviceDeactivated:
  536. {
  537. // Deactivated
  538. }
  539. break;
  540. case vr::VREvent_TrackedDeviceUpdated:
  541. {
  542. // Updated
  543. }
  544. break;
  545. }
  546. }
  547. void OpenVRProvider::updateTrackedPoses()
  548. {
  549. if (!mHMD)
  550. return;
  551. vr::VRCompositor()->WaitGetPoses(mTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, NULL, 0);
  552. mValidPoseCount = 0;
  553. for (int nDevice = 0; nDevice < vr::k_unMaxTrackedDeviceCount; ++nDevice)
  554. {
  555. IDevicePose &inPose = mCurrentDevicePose[nDevice];
  556. if (mTrackedDevicePose[nDevice].bPoseIsValid)
  557. {
  558. mValidPoseCount++;
  559. MatrixF mat = ConvertSteamVRAffineMatrixToMatrixFPlain(mTrackedDevicePose[nDevice].mDeviceToAbsoluteTracking);
  560. mat.inverse();
  561. if (nDevice == vr::k_unTrackedDeviceIndex_Hmd)
  562. {
  563. mHMDRenderState.mHMDPose = mat;
  564. }
  565. vr::TrackedDevicePose_t &outPose = mTrackedDevicePose[nDevice];
  566. OpenVRTransformToRotPos(mat, inPose.orientation, inPose.position);
  567. inPose.state = outPose.eTrackingResult;
  568. inPose.valid = outPose.bPoseIsValid;
  569. inPose.connected = outPose.bDeviceIsConnected;
  570. inPose.velocity = OpenVRVecToTorqueVec(outPose.vVelocity);
  571. inPose.angularVelocity = OpenVRVecToTorqueVec(outPose.vAngularVelocity);
  572. }
  573. else
  574. {
  575. inPose.valid = false;
  576. }
  577. }
  578. }
  579. void OpenVRProvider::submitInputChanges()
  580. {
  581. // Diff current frame with previous frame
  582. for (U32 i = 0; i < vr::k_unMaxTrackedDeviceCount; i++)
  583. {
  584. IDevicePose curPose = mCurrentDevicePose[i];
  585. IDevicePose prevPose = mPreviousInputTrackedDevicePose[i];
  586. if (!curPose.valid || !curPose.connected)
  587. continue;
  588. if (curPose.orientation != prevPose.orientation)
  589. {
  590. AngAxisF axisAA(curPose.orientation);
  591. INPUTMGR->buildInputEvent(mDeviceType, 0, SI_ROT, OVR_SENSORROT[i], SI_MOVE, axisAA);
  592. }
  593. if (curPose.position != prevPose.position)
  594. {
  595. INPUTMGR->buildInputEvent(mDeviceType, 0, SI_POS, OVR_SENSORPOSITION[i], SI_MOVE, curPose.position);
  596. }
  597. if (curPose.velocity != prevPose.velocity)
  598. {
  599. // Convert angles to degrees
  600. VectorF angles;
  601. angles.x = curPose.velocity.x;
  602. angles.y = curPose.velocity.y;
  603. angles.z = curPose.velocity.z;
  604. INPUTMGR->buildInputEvent(mDeviceType, 0, SI_POS, OVR_SENSORVELOCITY[i], SI_MOVE, angles);
  605. }
  606. if (curPose.angularVelocity != prevPose.angularVelocity)
  607. {
  608. // Convert angles to degrees
  609. VectorF angles;
  610. angles[0] = mRadToDeg(curPose.velocity.x);
  611. angles[1] = mRadToDeg(curPose.velocity.y);
  612. angles[2] = mRadToDeg(curPose.velocity.z);
  613. INPUTMGR->buildInputEvent(mDeviceType, 0, SI_POS, OVR_SENSORANGVEL[i], SI_MOVE, angles);
  614. }
  615. /*
  616. if (curPose.connected != prevPose.connected)
  617. {
  618. if (Con::isFunction("onOVRConnectionChanged"))
  619. {
  620. Con::executef("onOVRConnectionStatus", curPose.connected);
  621. }
  622. }*/
  623. if (curPose.state != prevPose.state)
  624. {
  625. if (Con::isFunction("onOVRStateChanged"))
  626. {
  627. Con::executef("onOVRStateChanged", curPose.state);
  628. }
  629. }
  630. }
  631. dMemcpy(mPreviousInputTrackedDevicePose, mCurrentDevicePose, sizeof(mPreviousInputTrackedDevicePose));
  632. }
  633. void OpenVRProvider::resetSensors()
  634. {
  635. if (mHMD)
  636. {
  637. mHMD->ResetSeatedZeroPose();
  638. }
  639. }
  640. DefineEngineFunction(isOpenVRDeviceActive, bool, (), ,
  641. "@brief Used to determine if the OpenVR input device is active\n\n"
  642. "The OpenVR device is considered active when the library has been "
  643. "initialized and either a real of simulated HMD is present.\n\n"
  644. "@return True if the OpenVR input device is active.\n"
  645. "@ingroup Game")
  646. {
  647. if (!ManagedSingleton<OpenVRProvider>::instanceOrNull())
  648. {
  649. return false;
  650. }
  651. return OCULUSVRDEV->getActive();
  652. }
  653. DefineEngineFunction(OpenVRSetEnabled, bool, (bool value), ,
  654. "@brief Used to determine if the OpenVR input device is active\n\n"
  655. "The OpenVR device is considered active when the library has been "
  656. "initialized and either a real of simulated HMD is present.\n\n"
  657. "@return True if the OpenVR input device is active.\n"
  658. "@ingroup Game")
  659. {
  660. if (!ManagedSingleton<OpenVRProvider>::instanceOrNull())
  661. {
  662. return false;
  663. }
  664. return value ? ManagedSingleton<OpenVRProvider>::instance()->enable() : ManagedSingleton<OpenVRProvider>::instance()->disable();
  665. }
  666. DefineEngineFunction(setOpenVRHMDAsGameConnectionDisplayDevice, bool, (GameConnection* conn), ,
  667. "@brief Sets the first HMD to be a GameConnection's display device\n\n"
  668. "@param conn The GameConnection to set.\n"
  669. "@return True if the GameConnection display device was set.\n"
  670. "@ingroup Game")
  671. {
  672. if (!ManagedSingleton<OpenVRProvider>::instanceOrNull())
  673. {
  674. Con::errorf("setOVRHMDAsGameConnectionDisplayDevice(): No Oculus VR Device present.");
  675. return false;
  676. }
  677. if (!conn)
  678. {
  679. Con::errorf("setOVRHMDAsGameConnectionDisplayDevice(): Invalid GameConnection.");
  680. return false;
  681. }
  682. conn->setDisplayDevice(ManagedSingleton<OpenVRProvider>::instance());
  683. return true;
  684. }
  685. DefineEngineFunction(OpenVRResetSensors, void, (), ,
  686. "@brief Resets all Oculus VR sensors.\n\n"
  687. "This resets all sensor orientations such that their 'normal' rotation "
  688. "is defined when this function is called. This defines an HMD's forwards "
  689. "and up direction, for example."
  690. "@ingroup Game")
  691. {
  692. if (!ManagedSingleton<OpenVRProvider>::instanceOrNull())
  693. {
  694. return;
  695. }
  696. ManagedSingleton<OpenVRProvider>::instance()->resetSensors();
  697. }