Torque3D Documentation / _generateds / openVROverlay.cpp

openVROverlay.cpp

Engine/source/platform/input/openVR/openVROverlay.cpp

More...

Public Variables

Public Functions

DefineEngineMethod(OpenVROverlay , hideOverlay , void , () , "" )
DefineEngineMethod(OpenVROverlay , showOverlay , void , () , "" )
ImplementEnumType(OpenVROverlayType , "Desired overlay type <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> OpenVROverlay. .\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@ingroup OpenVR" )
bool
setProtectedOverlayDirty(void * obj, const char * array, const char * data)
bool
setProtectedOverlayTypeDirty(void * obj, const char * array, const char * data)

Detailed Description

Public Variables

 EndImplementEnumType 

Public Functions

DefineEngineMethod(OpenVROverlay , hideOverlay , void , () , "" )

DefineEngineMethod(OpenVROverlay , showOverlay , void , () , "" )

IMPLEMENT_CONOBJECT(OpenVROverlay )

ImplementEnumType(OpenVROverlayType , "Desired overlay type <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> OpenVROverlay. .\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n\n</a>" "@ingroup OpenVR" )

setProtectedOverlayDirty(void * obj, const char * array, const char * data)

setProtectedOverlayTypeDirty(void * obj, const char * array, const char * data)

  1
  2#include "platform/input/openVR/openVRProvider.h"
  3#include "platform/input/openVR/openVROverlay.h"
  4
  5#include "gfx/D3D11/gfxD3D11Device.h"
  6#include "gfx/D3D11/gfxD3D11TextureObject.h"
  7#include "gfx/D3D11/gfxD3D11EnumTranslate.h"
  8
  9#ifdef TORQUE_OPENGL
 10#include "gfx/gl/gfxGLDevice.h"
 11#include "gfx/gl/gfxGLTextureObject.h"
 12#include "gfx/gl/gfxGLEnumTranslate.h"
 13#endif
 14
 15#include "postFx/postEffectCommon.h"
 16#include "gui/controls/guiTextEditCtrl.h"
 17
 18ImplementEnumType(OpenVROverlayType,
 19   "Desired overlay type for OpenVROverlay. .\n\n"
 20   "@ingroup OpenVR")
 21{ OpenVROverlay::OVERLAYTYPE_OVERLAY, "Overlay" },
 22{ OpenVROverlay::OVERLAYTYPE_DASHBOARD, "Dashboard" },
 23EndImplementEnumType;
 24
 25IMPLEMENT_CONOBJECT(OpenVROverlay);
 26
 27OpenVROverlay::OpenVROverlay()
 28{
 29   mTransform = MatrixF(1);
 30   mOverlayWidth = 1.5f;
 31   mOverlayFlags = 0;
 32
 33   mOverlayColor = LinearColorF(1, 1, 1, 1);
 34   mTrackingOrigin = vr::TrackingUniverseSeated;
 35
 36   mTargetFormat = GFXFormatR8G8B8A8_LINEAR_FORCE; // needed for openvr!
 37   mManualMouseHandling = true;
 38
 39   mMouseScale = Point2F(1, 1);
 40}
 41
 42OpenVROverlay::~OpenVROverlay()
 43{
 44
 45}
 46
 47static bool setProtectedOverlayTypeDirty(void *obj, const char *array, const char *data)
 48{
 49   OpenVROverlay *object = static_cast<OpenVROverlay*>(obj);
 50   object->mOverlayTypeDirty = true;
 51   return true;
 52}
 53
 54static bool setProtectedOverlayDirty(void *obj, const char *array, const char *data)
 55{
 56   OpenVROverlay *object = static_cast<OpenVROverlay*>(obj);
 57   object->mOverlayDirty = true;
 58   return true;
 59}
 60
 61void OpenVROverlay::initPersistFields()
 62{
 63   addProtectedField("overlayType", TypeOpenVROverlayType, Offset(mOverlayType, OpenVROverlay), &setProtectedOverlayTypeDirty, &defaultProtectedGetFn,
 64      "Type of overlay.");
 65   addProtectedField("overlayFlags", TypeS32, Offset(mOverlayFlags, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 66      "Flags for overlay.");
 67   addProtectedField("overlayWidth", TypeF32, Offset(mOverlayWidth, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 68      "Width of overlay.");
 69   addProtectedField("overlayColor", TypeColorF, Offset(mOverlayColor, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 70      "Backing color of overlay.");
 71
 72   addProtectedField("transformType", TypeOpenVROverlayTransformType, Offset(mOverlayTransformType, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 73      "Transform type of overlay.");
 74   addProtectedField("transformPosition", TypeMatrixPosition, Offset(mTransform, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 75      "Position of overlay.");
 76   addProtectedField("transformRotation", TypeMatrixRotation, Offset(mTransform, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 77      "Rotation of overlay.");
 78   addProtectedField("transformDeviceIndex", TypeS32, Offset(mTransformDeviceIndex, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 79      "Rotation of overlay.");
 80   addProtectedField("transformDeviceComponent", TypeString, Offset(mTransformDeviceComponent, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 81      "Rotation of overlay.");
 82
 83   addProtectedField("inputMethod", TypeOpenVROverlayInputMethod, Offset(mInputMethod, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 84      "Type of input method.");
 85   addProtectedField("mouseScale", TypePoint2F, Offset(mMouseScale, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 86      "Scale of mouse input.");
 87
 88   addProtectedField("trackingOrigin", TypeOpenVRTrackingUniverseOrigin, Offset(mTrackingOrigin, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 89      "Tracking origin.");
 90
 91   addProtectedField("controllerDevice", TypeS32, Offset(mControllerDeviceIndex, OpenVROverlay), &setProtectedOverlayDirty, &defaultProtectedGetFn,
 92      "Index of controller to attach overlay to.");
 93
 94   addField("manualMouseHandling", TypeBool, Offset(mManualMouseHandling, OpenVROverlay), "Forces openvr to create mouse events for overlay");
 95
 96   Parent::initPersistFields();
 97}
 98
 99bool OpenVROverlay::onAdd()
100{
101   if (Parent::onAdd())
102   {
103      mOverlayTypeDirty = true;
104      mOverlayDirty = true;
105
106      if (OPENVR)
107      {
108         OPENVR->registerOverlay(this);
109      }
110
111      return true;
112   }
113
114   return false;
115}
116
117void OpenVROverlay::onRemove()
118{
119   if (mOverlayHandle)
120   {
121      vr::VROverlay()->DestroyOverlay(mOverlayHandle);
122      mOverlayHandle = NULL;
123   }
124
125   if (mThumbOverlayHandle)
126   {
127      vr::VROverlay()->DestroyOverlay(mThumbOverlayHandle);
128      mThumbOverlayHandle = NULL;
129   }
130
131   if (ManagedSingleton<OpenVRProvider>::instanceOrNull())
132   {
133      OPENVR->unregisterOverlay(this);
134   }
135}
136
137void OpenVROverlay::resetOverlay()
138{
139   vr::IVROverlay *overlay = vr::VROverlay();
140   if (!overlay)
141      return;
142
143   if (mOverlayHandle)
144   {
145      overlay->DestroyOverlay(mOverlayHandle);
146      mOverlayHandle = NULL;
147   }
148
149   if (mThumbOverlayHandle)
150   {
151      overlay->DestroyOverlay(mThumbOverlayHandle);
152      mThumbOverlayHandle = NULL;
153   }
154
155   if (mOverlayType == OpenVROverlay::OVERLAYTYPE_DASHBOARD)
156   {
157      overlay->CreateDashboardOverlay(mInternalName, mInternalName, &mOverlayHandle, &mThumbOverlayHandle);
158   }
159   else
160   {
161      overlay->CreateOverlay(mInternalName, mInternalName, &mOverlayHandle);
162   }
163
164   mOverlayDirty = true;
165   mOverlayTypeDirty = false;
166
167   // Pre-render start frame so we have a texture available
168   if (!mTarget)
169   {
170      renderFrame(false, false);
171   }
172}
173
174void OpenVROverlay::updateOverlay()
175{
176   if (mOverlayTypeDirty)
177      resetOverlay();
178
179   // Update params
180   vr::IVROverlay *overlay = vr::VROverlay();
181   if (!overlay || !mOverlayHandle)
182      return;
183
184   if (!mOverlayDirty)
185      return;
186
187   MatrixF vrMat(1);
188   vr::HmdMatrix34_t ovrMat;
189   vr::HmdVector2_t ovrMouseScale;
190   ovrMouseScale.v[0] = mMouseScale.x;
191   ovrMouseScale.v[1] = mMouseScale.y;
192
193   OpenVRUtil::convertTransformToOVR(mTransform, vrMat);
194   OpenVRUtil::convertMatrixFPlainToSteamVRAffineMatrix(vrMat, ovrMat);
195
196   MatrixF reverseMat = OpenVRUtil::convertSteamVRAffineMatrixToMatrixFPlain(ovrMat);
197   MatrixF finalReverseMat(1);
198   OpenVRUtil::convertTransformFromOVR(reverseMat, finalReverseMat);
199
200   switch (mOverlayTransformType)
201   {
202      case vr::VROverlayTransform_Absolute:
203         overlay->SetOverlayTransformAbsolute(mOverlayHandle, mTrackingOrigin, &ovrMat);
204         break;
205      case vr::VROverlayTransform_TrackedDeviceRelative:
206         overlay->SetOverlayTransformTrackedDeviceRelative(mOverlayHandle, mTransformDeviceIndex, &ovrMat);
207         break;
208      case vr::VROverlayTransform_TrackedComponent:
209         overlay->SetOverlayTransformTrackedDeviceComponent(mOverlayHandle, mTransformDeviceIndex, mTransformDeviceComponent.c_str());
210         break;
211      // NOTE: system not handled here - doesn't seem possible to create these
212      default:
213         break;
214   }
215
216  // overlay->SetOverlayColor(mOverlayHandle, mOverlayColor.red, mOverlayColor.green, mOverlayColor.blue);
217   overlay->SetOverlayAlpha(mOverlayHandle, mOverlayColor.alpha);
218   overlay->SetOverlayMouseScale(mOverlayHandle, &ovrMouseScale);
219   overlay->SetOverlayInputMethod(mOverlayHandle, mInputMethod);
220   overlay->SetOverlayWidthInMeters(mOverlayHandle, mOverlayWidth);
221
222   // NOTE: if flags in openvr change, double check this
223   for (U32 i = vr::VROverlayFlags_None; i <= vr::VROverlayFlags_ShowTouchPadScrollWheel; i++)
224   {
225      overlay->SetOverlayFlag(mOverlayHandle, (vr::VROverlayFlags)i, mOverlayFlags & (1 << i));
226   }
227
228   mOverlayDirty = false;
229}
230
231void OpenVROverlay::showOverlay()
232{
233   updateOverlay();
234   if (mOverlayHandle == NULL)
235      return;
236
237   if (mOverlayType != OVERLAYTYPE_DASHBOARD)
238   {
239      vr::EVROverlayError err = vr::VROverlay()->ShowOverlay(mOverlayHandle);
240      if (err != vr::VROverlayError_None)
241      {
242         Con::errorf("VR Overlay error!");
243      }
244   }
245
246   if (!mStagingTexture)
247   {
248      renderFrame(false, false);
249   }
250}
251
252void OpenVROverlay::hideOverlay()
253{
254   if (mOverlayHandle == NULL)
255      return;
256
257   if (mOverlayType != OVERLAYTYPE_DASHBOARD)
258   {
259      vr::VROverlay()->HideOverlay(mOverlayHandle);
260   }
261}
262
263
264bool OpenVROverlay::isOverlayVisible()
265{
266   if (mOverlayHandle == NULL)
267      return false;
268
269   return vr::VROverlay()->IsOverlayVisible(mOverlayHandle);
270}
271
272bool OpenVROverlay::isOverlayHoverTarget()
273{
274   if (mOverlayHandle == NULL)
275      return false;
276
277   return vr::VROverlay()->IsHoverTargetOverlay(mOverlayHandle);
278}
279
280
281bool OpenVROverlay::isGamepadFocussed()
282{
283   if (mOverlayHandle == NULL)
284      return false;
285
286   return vr::VROverlay()->GetGamepadFocusOverlay() == mOverlayHandle;
287}
288
289bool OpenVROverlay::isActiveDashboardOverlay()
290{
291   return false; // TODO WHERE DID I GET THIS FROM
292}
293
294MatrixF OpenVROverlay::getTransformForOverlayCoordinates(const Point2F &pos)
295{
296   if (mOverlayHandle == NULL)
297      return MatrixF::Identity;
298
299   vr::HmdVector2_t vec;
300   vec.v[0] = pos.x;
301   vec.v[1] = pos.y;
302   vr::HmdMatrix34_t outMat;
303   MatrixF outTorqueMat;
304   if (vr::VROverlay()->GetTransformForOverlayCoordinates(mOverlayHandle, mTrackingOrigin, vec, &outMat) != vr::VROverlayError_None)
305      return MatrixF::Identity;
306
307   MatrixF vrMat(1);
308   vrMat = OpenVRUtil::convertSteamVRAffineMatrixToMatrixFPlain(outMat);
309   OpenVRUtil::convertTransformFromOVR(vrMat, outTorqueMat);
310   return outTorqueMat;
311}
312
313bool OpenVROverlay::castRay(const Point3F &origin, const Point3F &direction, RayInfo *info)
314{
315   if (mOverlayHandle == NULL)
316      return false;
317
318   vr::VROverlayIntersectionParams_t params;
319   vr::VROverlayIntersectionResults_t result;
320
321   Point3F ovrOrigin = OpenVRUtil::convertPointToOVR(origin);
322   Point3F ovrDirection = OpenVRUtil::convertPointToOVR(direction);
323
324   params.eOrigin = mTrackingOrigin;
325   params.vSource.v[0] = ovrOrigin.x;
326   params.vSource.v[1] = ovrOrigin.y;
327   params.vSource.v[2] = ovrOrigin.z;
328   params.vDirection.v[0] = ovrDirection.x;
329   params.vDirection.v[1] = ovrDirection.y;
330   params.vDirection.v[2] = ovrDirection.z;
331
332   bool rayHit = vr::VROverlay()->ComputeOverlayIntersection(mOverlayHandle, &params, &result);
333
334   if (rayHit && info)
335   {
336      info->t = result.fDistance;
337      info->point = OpenVRUtil::convertPointFromOVR(result.vPoint); // TODO: need to transform this FROM vr-space
338      info->normal = OpenVRUtil::convertPointFromOVR(result.vNormal);
339      info->texCoord = Point2F(result.vUVs.v[0], result.vUVs.v[1]);
340      info->object = NULL;
341      info->userData = this;
342   }
343
344   return rayHit;
345}
346
347void OpenVROverlay::moveGamepadFocusToNeighbour()
348{
349
350}
351
352void OpenVROverlay::handleOpenVREvents()
353{
354   if (mManualMouseHandling)
355   {
356      // tell OpenVR to make some events for us
357      for (vr::TrackedDeviceIndex_t unDeviceId = 1; unDeviceId < vr::k_unControllerStateAxisCount; unDeviceId++)
358      {
359         if (vr::VROverlay()->HandleControllerOverlayInteractionAsMouse(mOverlayHandle, unDeviceId))
360         {
361            break;
362         }
363      }
364   }
365
366
367   vr::VREvent_t vrEvent;
368   while (vr::VROverlay()->PollNextOverlayEvent(mOverlayHandle, &vrEvent, sizeof(vrEvent)))
369   {
370      InputEventInfo eventInfo;
371      eventInfo.deviceType = MouseDeviceType;
372      eventInfo.deviceInst = 0;
373      eventInfo.objType = SI_AXIS;
374      eventInfo.modifier = (InputModifiers)0;
375      eventInfo.ascii = 0;
376
377      //Con::printf("Overlay event %i", vrEvent.eventType);
378
379      switch (vrEvent.eventType)
380      {
381      case vr::VREvent_MouseMove:
382      {
383         //Con::printf("mousemove %f,%f", vrEvent.data.mouse.x, vrEvent.data.mouse.y);
384         eventInfo.objType = SI_AXIS;
385         eventInfo.objInst = SI_XAXIS;
386         eventInfo.action = SI_MAKE;
387         eventInfo.fValue = getExtent().x * vrEvent.data.mouse.x;
388         processMouseEvent(eventInfo);
389
390         eventInfo.objType = SI_AXIS;
391         eventInfo.objInst = SI_YAXIS;
392         eventInfo.action = SI_MAKE;
393         eventInfo.fValue = getExtent().y * (1.0 - vrEvent.data.mouse.y);
394         processMouseEvent(eventInfo);
395      }
396      break;
397
398      case vr::VREvent_MouseButtonDown:
399      {
400         eventInfo.objType = SI_BUTTON;
401         eventInfo.objInst = (InputObjectInstances)OpenVRUtil::convertOpenVRButtonToTorqueButton(vrEvent.data.mouse.button);
402         eventInfo.action = SI_MAKE;
403         eventInfo.fValue = 1.0f;
404         processMouseEvent(eventInfo);
405      }
406      break;
407
408      case vr::VREvent_MouseButtonUp:
409      {
410         eventInfo.objType = SI_BUTTON;
411         eventInfo.objInst = (InputObjectInstances)OpenVRUtil::convertOpenVRButtonToTorqueButton(vrEvent.data.mouse.button);
412         eventInfo.action = SI_BREAK;
413         eventInfo.fValue = 0.0f;
414         processMouseEvent(eventInfo);
415      }
416      break;
417
418      case vr::VREvent_OverlayShown:
419      {
420         markDirty();
421      }
422      break;
423
424      case vr::VREvent_Quit:
425         AssertFatal(false, "WTF is going on here");
426         break;
427
428      case vr::VREvent_KeyboardCharInput:
429      case vr::VREvent_KeyboardDone:
430         updateTextControl((GuiControl*)vrEvent.data.keyboard.uUserValue);
431         break;
432      }
433
434   }
435
436   if (mThumbOverlayHandle != vr::k_ulOverlayHandleInvalid)
437   {
438      while (vr::VROverlay()->PollNextOverlayEvent(mThumbOverlayHandle, &vrEvent, sizeof(vrEvent)))
439      {
440         switch (vrEvent.eventType)
441         {
442         case vr::VREvent_OverlayShown:
443         {
444            markDirty();
445         }
446         break;
447         }
448      }
449   }
450}
451
452void OpenVROverlay::updateTextControl(GuiControl* ctrl)
453{
454   if (!ctrl)
455      return;
456
457   GuiTextCtrl* textCtrl = dynamic_cast<GuiTextCtrl*>(ctrl);
458   if (textCtrl)
459   {
460      char text[GuiTextCtrl::MAX_STRING_LENGTH];
461      vr::VROverlay()->GetKeyboardText(text, GuiTextCtrl::MAX_STRING_LENGTH);
462      textCtrl->setText(text);
463   }
464}
465
466void OpenVROverlay::onFrameRendered()
467{
468   vr::IVROverlay *overlay = vr::VROverlay();
469   if (!overlay || !mOverlayHandle)
470      return;
471
472   updateOverlay();
473
474   Point2I desiredSize = mTarget->getSize();
475   if (mStagingTexture.isNull() || mStagingTexture.getWidthHeight() != desiredSize)
476   {
477      Point2I sz = mStagingTexture.getWidthHeight();
478      mStagingTexture.set(desiredSize.x, desiredSize.y, mTargetFormat, &VRTextureProfile, "OpenVROverlay staging texture");
479   }
480   mTarget->resolveTo(mStagingTexture);
481
482   vr::Texture_t tex;
483   if (GFX->getAdapterType() == Direct3D11)
484   {
485      tex = { (void*)static_cast<GFXD3D11TextureObject*>(mStagingTexture.getPointer())->getResource(), vr::API_DirectX, vr::ColorSpace_Auto };
486   }
487#ifdef TORQUE_OPENGL
488   else if (GFX->getAdapterType() == OpenGL)
489   {
490      tex = { (void*)static_cast<GFXGLTextureObject*>(mStagingTexture.getPointer())->getHandle(), vr::API_OpenGL, vr::ColorSpace_Auto };
491
492   }
493#endif
494   else
495   {
496      return;
497   }
498
499   //mStagingTexture->dumpToDisk("PNG", "D:\\test.png");
500
501   vr::EVROverlayError err = overlay->SetOverlayTexture(mOverlayHandle, &tex);
502   if (err != vr::VROverlayError_None)
503   {
504      Con::errorf("VR: Error setting overlay texture.");
505   }
506
507   //Con::printf("Overlay visible ? %s", vr::VROverlay()->IsOverlayVisible(mOverlayHandle) ? "YES" : "NO");
508}
509
510void OpenVROverlay::enableKeyboardTranslation()
511{
512   vr::IVROverlay *overlay = vr::VROverlay();
513   if (!overlay || !mOverlayHandle)
514      return;
515
516   GuiTextEditCtrl* ctrl = dynamic_cast<GuiTextEditCtrl*>(getFirstResponder());
517   if (ctrl)
518   {
519      vr::EGamepadTextInputMode inputMode = ctrl->isPasswordText() ? vr::k_EGamepadTextInputModePassword : vr::k_EGamepadTextInputModeNormal;
520      char text[GuiTextCtrl::MAX_STRING_LENGTH + 1];
521      ctrl->getText(text);
522      overlay->ShowKeyboardForOverlay(mOverlayHandle, inputMode, vr::k_EGamepadTextInputLineModeSingleLine, ctrl->getTooltip().c_str(), GuiTextCtrl::MAX_STRING_LENGTH, text, false, (uint64_t)ctrl);
523   }
524}
525
526void OpenVROverlay::disableKeyboardTranslation()
527{
528   vr::IVROverlay *overlay = vr::VROverlay();
529   if (!overlay || !mOverlayHandle)
530      return;
531
532   overlay->HideKeyboard();
533}
534
535void OpenVROverlay::setNativeAcceleratorsEnabled(bool enabled)
536{
537}
538
539DefineEngineMethod(OpenVROverlay, showOverlay, void, (), , "")
540{
541   object->showOverlay();
542}
543
544DefineEngineMethod(OpenVROverlay, hideOverlay, void, (), , "")
545{
546   object->hideOverlay();
547}
548