openVROverlay.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. #include "platform/input/openVR/openVRProvider.h"
  2. #include "platform/input/openVR/openVROverlay.h"
  3. #include "gfx/D3D11/gfxD3D11Device.h"
  4. #include "gfx/D3D11/gfxD3D11TextureObject.h"
  5. #include "gfx/D3D11/gfxD3D11EnumTranslate.h"
  6. #ifdef TORQUE_OPENGL
  7. #include "gfx/gl/gfxGLDevice.h"
  8. #include "gfx/gl/gfxGLTextureObject.h"
  9. #include "gfx/gl/gfxGLEnumTranslate.h"
  10. #endif
  11. #include "postFx/postEffectCommon.h"
  12. ImplementEnumType(OpenVROverlayType,
  13. "Desired overlay type for OpenVROverlay. .\n\n"
  14. "@ingroup OpenVR")
  15. { OpenVROverlay::OVERLAYTYPE_OVERLAY, "Overlay" },
  16. { OpenVROverlay::OVERLAYTYPE_DASHBOARD, "Dashboard" },
  17. EndImplementEnumType;
  18. IMPLEMENT_CONOBJECT(OpenVROverlay);
  19. OpenVROverlay::OpenVROverlay()
  20. {
  21. mTransform = MatrixF(1);
  22. mOverlayWidth = 1.5f;
  23. mOverlayFlags = 0;
  24. mOverlayColor = ColorF(1, 1, 1, 1);
  25. mTrackingOrigin = vr::TrackingUniverseSeated;
  26. mTargetFormat = GFXFormatR8G8B8A8_LINEAR_FORCE; // needed for openvr!
  27. }
  28. OpenVROverlay::~OpenVROverlay()
  29. {
  30. }
  31. static bool setProtectedOverlayTypeDirty(void *obj, const char *array, const char *data)
  32. {
  33. OpenVROverlay *object = static_cast<OpenVROverlay*>(obj);
  34. object->mOverlayTypeDirty = true;
  35. return true;
  36. }
  37. static bool setProtectedOverlayDirty(void *obj, const char *array, const char *data)
  38. {
  39. OpenVROverlay *object = static_cast<OpenVROverlay*>(obj);
  40. object->mOverlayDirty = true;
  41. return true;
  42. }
  43. void OpenVROverlay::initPersistFields()
  44. {
  45. addProtectedField("overlayType", TypeOpenVROverlayType, Offset(mOverlayType, OpenVROverlay), &setProtectedOverlayTypeDirty, &defaultProtectedGetFn,
  46. "Type of overlay.");
  47. addProtectedField("overlayFlags", TypeS32, Offset(mOverlayFlags, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  48. "Flags for overlay.");
  49. addProtectedField("overlayWidth", TypeS32, Offset(mOverlayWidth, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  50. "Width of overlay.");
  51. addProtectedField("overlayColor", TypeColorF, Offset(mOverlayColor, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  52. "Backing color of overlay.");
  53. addProtectedField("transformType", TypeOpenVROverlayTransformType, Offset(mOverlayTransformType, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  54. "Transform type of overlay.");
  55. addProtectedField("transformPosition", TypeMatrixPosition, Offset(mTransform, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  56. "Position of overlay.");
  57. addProtectedField("transformRotation", TypeMatrixRotation, Offset(mTransform, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  58. "Rotation of overlay.");
  59. addProtectedField("transformDeviceIndex", TypeS32, Offset(mTransformDeviceIndex, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  60. "Rotation of overlay.");
  61. addProtectedField("transformDeviceComponent", TypeString, Offset(mTransformDeviceComponent, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  62. "Rotation of overlay.");
  63. addProtectedField("inputMethod", TypeOpenVROverlayInputMethod, Offset(mTransformDeviceComponent, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  64. "Type of input method.");
  65. addProtectedField("mouseScale", TypePoint2F, Offset(mMouseScale, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  66. "Scale of mouse input.");
  67. addProtectedField("trackingOrigin", TypeOpenVRTrackingUniverseOrigin, Offset(mTrackingOrigin, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  68. "Tracking origin.");
  69. addProtectedField("controllerDevice", TypeS32, Offset(mControllerDeviceIndex, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
  70. "Index of controller to attach overlay to.");
  71. Parent::initPersistFields();
  72. }
  73. bool OpenVROverlay::onAdd()
  74. {
  75. if (Parent::onAdd())
  76. {
  77. mOverlayTypeDirty = true;
  78. mOverlayDirty = true;
  79. return true;
  80. }
  81. return false;
  82. }
  83. void OpenVROverlay::onRemove()
  84. {
  85. if (mOverlayHandle)
  86. {
  87. vr::VROverlay()->DestroyOverlay(mOverlayHandle);
  88. mOverlayHandle = NULL;
  89. }
  90. if (mThumbOverlayHandle)
  91. {
  92. vr::VROverlay()->DestroyOverlay(mThumbOverlayHandle);
  93. mThumbOverlayHandle = NULL;
  94. }
  95. }
  96. void OpenVROverlay::resetOverlay()
  97. {
  98. vr::IVROverlay *overlay = vr::VROverlay();
  99. if (!overlay)
  100. return;
  101. if (mOverlayHandle)
  102. {
  103. overlay->DestroyOverlay(mOverlayHandle);
  104. mOverlayHandle = NULL;
  105. }
  106. if (mThumbOverlayHandle)
  107. {
  108. overlay->DestroyOverlay(mThumbOverlayHandle);
  109. mThumbOverlayHandle = NULL;
  110. }
  111. if (mOverlayType == OpenVROverlay::OVERLAYTYPE_DASHBOARD)
  112. {
  113. overlay->CreateDashboardOverlay(mInternalName, mInternalName, &mOverlayHandle, &mThumbOverlayHandle);
  114. }
  115. else
  116. {
  117. overlay->CreateOverlay(mInternalName, mInternalName, &mOverlayHandle);
  118. }
  119. mOverlayDirty = true;
  120. mOverlayTypeDirty = false;
  121. // Pre-render start frame so we have a texture available
  122. if (!mTarget)
  123. {
  124. renderFrame(false, false);
  125. }
  126. }
  127. void OpenVROverlay::updateOverlay()
  128. {
  129. if (mOverlayTypeDirty)
  130. resetOverlay();
  131. // Update params
  132. vr::IVROverlay *overlay = vr::VROverlay();
  133. if (!overlay || !mOverlayHandle)
  134. return;
  135. if (!mOverlayDirty)
  136. return;
  137. MatrixF vrMat(1);
  138. vr::HmdMatrix34_t ovrMat;
  139. vr::HmdVector2_t ovrMouseScale;
  140. ovrMouseScale.v[0] = mMouseScale.x;
  141. ovrMouseScale.v[1] = mMouseScale.y;
  142. OpenVRUtil::convertTransformToOVR(mTransform, vrMat);
  143. OpenVRUtil::convertMatrixFPlainToSteamVRAffineMatrix(vrMat, ovrMat);
  144. MatrixF reverseMat = OpenVRUtil::convertSteamVRAffineMatrixToMatrixFPlain(ovrMat);
  145. MatrixF finalReverseMat(1);
  146. OpenVRUtil::convertTransformFromOVR(reverseMat, finalReverseMat);
  147. switch (mOverlayTransformType)
  148. {
  149. case vr::VROverlayTransform_Absolute:
  150. overlay->SetOverlayTransformAbsolute(mOverlayHandle, mTrackingOrigin, &ovrMat);
  151. break;
  152. case vr::VROverlayTransform_TrackedDeviceRelative:
  153. overlay->SetOverlayTransformTrackedDeviceRelative(mOverlayHandle, mTransformDeviceIndex, &ovrMat);
  154. break;
  155. case vr::VROverlayTransform_TrackedComponent:
  156. overlay->SetOverlayTransformTrackedDeviceComponent(mOverlayHandle, mTransformDeviceIndex, mTransformDeviceComponent.c_str());
  157. break;
  158. // NOTE: system not handled here - doesn't seem possible to create these
  159. default:
  160. break;
  161. }
  162. // overlay->SetOverlayColor(mOverlayHandle, mOverlayColor.red, mOverlayColor.green, mOverlayColor.blue);
  163. overlay->SetOverlayAlpha(mOverlayHandle, mOverlayColor.alpha);
  164. overlay->SetOverlayMouseScale(mOverlayHandle, &ovrMouseScale);
  165. overlay->SetOverlayInputMethod(mOverlayHandle, mInputMethod);
  166. overlay->SetOverlayWidthInMeters(mOverlayHandle, mOverlayWidth);
  167. // NOTE: if flags in openvr change, double check this
  168. /*for (U32 i = vr::VROverlayFlags_None; i <= vr::VROverlayFlags_ShowTouchPadScrollWheel; i++)
  169. {
  170. overlay->SetOverlayFlag(mOverlayHandle, (vr::VROverlayFlags)i, mOverlayFlags & (1 << i));
  171. }*/
  172. mOverlayDirty = false;
  173. }
  174. void OpenVROverlay::showOverlay()
  175. {
  176. updateOverlay();
  177. if (mOverlayHandle == NULL)
  178. return;
  179. vr::EVROverlayError err = vr::VROverlay()->ShowOverlay(mOverlayHandle);
  180. if (err != vr::VROverlayError_None)
  181. {
  182. Con::errorf("VR Overlay error!");
  183. }
  184. if (!mStagingTexture)
  185. {
  186. renderFrame(false, false);
  187. }
  188. }
  189. void OpenVROverlay::hideOverlay()
  190. {
  191. if (mOverlayHandle == NULL)
  192. return;
  193. vr::VROverlay()->HideOverlay(mOverlayHandle);
  194. }
  195. bool OpenVROverlay::isOverlayVisible()
  196. {
  197. if (mOverlayHandle == NULL)
  198. return false;
  199. return vr::VROverlay()->IsOverlayVisible(mOverlayHandle);
  200. }
  201. bool OpenVROverlay::isOverlayHoverTarget()
  202. {
  203. if (mOverlayHandle == NULL)
  204. return false;
  205. return vr::VROverlay()->IsHoverTargetOverlay(mOverlayHandle);
  206. }
  207. bool OpenVROverlay::isGamepadFocussed()
  208. {
  209. if (mOverlayHandle == NULL)
  210. return false;
  211. return vr::VROverlay()->GetGamepadFocusOverlay() == mOverlayHandle;
  212. }
  213. bool OpenVROverlay::isActiveDashboardOverlay()
  214. {
  215. return false; // TODO WHERE DID I GET THIS FROM
  216. }
  217. MatrixF OpenVROverlay::getTransformForOverlayCoordinates(const Point2F &pos)
  218. {
  219. if (mOverlayHandle == NULL)
  220. return MatrixF::Identity;
  221. vr::HmdVector2_t vec;
  222. vec.v[0] = pos.x;
  223. vec.v[1] = pos.y;
  224. vr::HmdMatrix34_t outMat;
  225. MatrixF outTorqueMat;
  226. if (vr::VROverlay()->GetTransformForOverlayCoordinates(mOverlayHandle, mTrackingOrigin, vec, &outMat) != vr::VROverlayError_None)
  227. return MatrixF::Identity;
  228. MatrixF vrMat(1);
  229. vrMat = OpenVRUtil::convertSteamVRAffineMatrixToMatrixFPlain(outMat);
  230. OpenVRUtil::convertTransformFromOVR(vrMat, outTorqueMat);
  231. return outTorqueMat;
  232. }
  233. bool OpenVROverlay::castRay(const Point3F &origin, const Point3F &direction, RayInfo *info)
  234. {
  235. if (mOverlayHandle == NULL)
  236. return false;
  237. vr::VROverlayIntersectionParams_t params;
  238. vr::VROverlayIntersectionResults_t result;
  239. params.eOrigin = mTrackingOrigin;
  240. params.vSource.v[0] = origin.x;
  241. params.vSource.v[1] = origin.y;
  242. params.vSource.v[2] = origin.z;
  243. params.vDirection.v[0] = direction.x; // TODO: need to transform this to vr-space
  244. params.vDirection.v[1] = direction.y;
  245. params.vDirection.v[2] = direction.z;
  246. bool rayHit = vr::VROverlay()->ComputeOverlayIntersection(mOverlayHandle, &params, &result);
  247. if (rayHit && info)
  248. {
  249. info->t = result.fDistance;
  250. info->point = Point3F(result.vPoint.v[0], result.vPoint.v[1], result.vPoint.v[2]); // TODO: need to transform this FROM vr-space
  251. info->normal = Point3F(result.vNormal.v[0], result.vNormal.v[1], result.vNormal.v[2]);
  252. info->texCoord = Point2F(result.vUVs.v[0], result.vUVs.v[1]);
  253. info->object = NULL;
  254. info->userData = this;
  255. }
  256. return rayHit;
  257. }
  258. void OpenVROverlay::moveGamepadFocusToNeighbour()
  259. {
  260. }
  261. void OpenVROverlay::handleOpenVREvents()
  262. {
  263. vr::VREvent_t vrEvent;
  264. while (vr::VROverlay()->PollNextOverlayEvent(mOverlayHandle, &vrEvent, sizeof(vrEvent)))
  265. {
  266. InputEventInfo eventInfo;
  267. eventInfo.deviceType = MouseDeviceType;
  268. eventInfo.deviceInst = 0;
  269. eventInfo.objType = SI_AXIS;
  270. eventInfo.modifier = (InputModifiers)0;
  271. eventInfo.ascii = 0;
  272. switch (vrEvent.eventType)
  273. {
  274. case vr::VREvent_MouseMove:
  275. {
  276. eventInfo.objType = SI_AXIS;
  277. eventInfo.objInst = SI_XAXIS;
  278. eventInfo.action = SI_MAKE;
  279. eventInfo.fValue = vrEvent.data.mouse.x;
  280. processMouseEvent(eventInfo);
  281. eventInfo.objType = SI_AXIS;
  282. eventInfo.objInst = SI_YAXIS;
  283. eventInfo.action = SI_MAKE;
  284. eventInfo.fValue = vrEvent.data.mouse.y;
  285. processMouseEvent(eventInfo);
  286. }
  287. break;
  288. case vr::VREvent_MouseButtonDown:
  289. {
  290. eventInfo.objType = SI_BUTTON;
  291. eventInfo.objInst = (InputObjectInstances)OpenVRUtil::convertOpenVRButtonToTorqueButton(vrEvent.data.mouse.button);
  292. eventInfo.action = SI_MAKE;
  293. eventInfo.fValue = 1.0f;
  294. processMouseEvent(eventInfo);
  295. }
  296. break;
  297. case vr::VREvent_MouseButtonUp:
  298. {
  299. eventInfo.objType = SI_BUTTON;
  300. eventInfo.objInst = (InputObjectInstances)OpenVRUtil::convertOpenVRButtonToTorqueButton(vrEvent.data.mouse.button);
  301. eventInfo.action = SI_BREAK;
  302. eventInfo.fValue = 0.0f;
  303. processMouseEvent(eventInfo);
  304. }
  305. break;
  306. case vr::VREvent_OverlayShown:
  307. {
  308. markDirty();
  309. }
  310. break;
  311. case vr::VREvent_Quit:
  312. AssertFatal(false, "WTF is going on here");
  313. break;
  314. }
  315. }
  316. if (mThumbOverlayHandle != vr::k_ulOverlayHandleInvalid)
  317. {
  318. while (vr::VROverlay()->PollNextOverlayEvent(mThumbOverlayHandle, &vrEvent, sizeof(vrEvent)))
  319. {
  320. switch (vrEvent.eventType)
  321. {
  322. case vr::VREvent_OverlayShown:
  323. {
  324. markDirty();
  325. }
  326. break;
  327. }
  328. }
  329. }
  330. }
  331. void OpenVROverlay::onFrameRendered()
  332. {
  333. vr::IVROverlay *overlay = vr::VROverlay();
  334. if (!overlay || !mOverlayHandle)
  335. return;
  336. updateOverlay();
  337. Point2I desiredSize = mTarget->getSize();
  338. if (mStagingTexture.isNull() || mStagingTexture.getWidthHeight() != desiredSize)
  339. {
  340. Point2I sz = mStagingTexture.getWidthHeight();
  341. mStagingTexture.set(desiredSize.x, desiredSize.y, mTargetFormat, &VRTextureProfile, "OpenVROverlay staging texture");
  342. }
  343. mTarget->resolveTo(mStagingTexture);
  344. vr::Texture_t tex;
  345. if (GFX->getAdapterType() == Direct3D11)
  346. {
  347. tex = { (void*)static_cast<GFXD3D11TextureObject*>(mStagingTexture.getPointer())->getResource(), vr::API_DirectX, vr::ColorSpace_Auto };
  348. }
  349. #ifdef TORQUE_OPENGL
  350. else if (GFX->getAdapterType() == OpenGL)
  351. {
  352. tex = { (void*)static_cast<GFXGLTextureObject*>(mStagingTexture.getPointer())->getHandle(), vr::API_OpenGL, vr::ColorSpace_Auto };
  353. }
  354. #endif
  355. else
  356. {
  357. return;
  358. }
  359. //mStagingTexture->dumpToDisk("PNG", "D:\\test.png");
  360. vr::EVROverlayError err = overlay->SetOverlayTexture(mOverlayHandle, &tex);
  361. if (err != vr::VROverlayError_None)
  362. {
  363. Con::errorf("VR: Error setting overlay texture.");
  364. }
  365. //Con::printf("Overlay visible ? %s", vr::VROverlay()->IsOverlayVisible(mOverlayHandle) ? "YES" : "NO");
  366. }
  367. DefineEngineMethod(OpenVROverlay, showOverlay, void, (), , "")
  368. {
  369. object->showOverlay();
  370. }
  371. DefineEngineMethod(OpenVROverlay, hideOverlay, void, (), , "")
  372. {
  373. object->hideOverlay();
  374. }