openVRProvider.cpp 28 KB

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