Bug 1344393 - Add StageParameters for Oculus
MozReview-Commit-ID: 9OkleewwS2b
--- a/gfx/vr/gfxVROculus.cpp
+++ b/gfx/vr/gfxVROculus.cpp
@@ -93,16 +93,17 @@ static pfn_ovr_SetBool ovr_SetBool = nul
static pfn_ovr_GetInt ovr_GetInt = nullptr;
static pfn_ovr_SetInt ovr_SetInt = nullptr;
static pfn_ovr_GetFloat ovr_GetFloat = nullptr;
static pfn_ovr_SetFloat ovr_SetFloat = nullptr;
static pfn_ovr_GetFloatArray ovr_GetFloatArray = nullptr;
static pfn_ovr_SetFloatArray ovr_SetFloatArray = nullptr;
static pfn_ovr_GetString ovr_GetString = nullptr;
static pfn_ovr_SetString ovr_SetString = nullptr;
+static pfn_ovr_GetBoundaryDimensions ovr_GetBoundaryDimensions = nullptr;
#ifdef XP_WIN
static pfn_ovr_CreateTextureSwapChainDX ovr_CreateTextureSwapChainDX = nullptr;
static pfn_ovr_GetTextureSwapChainBufferDX ovr_GetTextureSwapChainBufferDX = nullptr;
static pfn_ovr_CreateMirrorTextureDX ovr_CreateMirrorTextureDX = nullptr;
static pfn_ovr_GetMirrorTextureBufferDX ovr_GetMirrorTextureBufferDX = nullptr;
#endif
@@ -281,16 +282,17 @@ InitializeOculusCAPI()
REQUIRE_FUNCTION(ovr_GetInt);
REQUIRE_FUNCTION(ovr_SetInt);
REQUIRE_FUNCTION(ovr_GetFloat);
REQUIRE_FUNCTION(ovr_SetFloat);
REQUIRE_FUNCTION(ovr_GetFloatArray);
REQUIRE_FUNCTION(ovr_SetFloatArray);
REQUIRE_FUNCTION(ovr_GetString);
REQUIRE_FUNCTION(ovr_SetString);
+ REQUIRE_FUNCTION(ovr_GetBoundaryDimensions);
#ifdef XP_WIN
REQUIRE_FUNCTION(ovr_CreateTextureSwapChainDX);
REQUIRE_FUNCTION(ovr_GetTextureSwapChainBufferDX);
REQUIRE_FUNCTION(ovr_CreateMirrorTextureDX);
REQUIRE_FUNCTION(ovr_GetMirrorTextureBufferDX);
@@ -351,16 +353,17 @@ VRDisplayOculus::VRDisplayOculus(ovrSess
, mQuadVS(nullptr)
, mQuadPS(nullptr)
, mLinearSamplerState(nullptr)
, mVSConstantBuffer(nullptr)
, mPSConstantBuffer(nullptr)
, mVertexBuffer(nullptr)
, mInputLayout(nullptr)
, mIsPresenting(false)
+ , mEyeHeight(OVR_DEFAULT_EYE_HEIGHT)
{
MOZ_COUNT_CTOR_INHERITED(VRDisplayOculus, VRDisplayHost);
mDisplayInfo.mDisplayName.AssignLiteral("Oculus VR HMD");
mDisplayInfo.mIsConnected = true;
mDisplayInfo.mIsMounted = false;
mDesc = ovr_GetHmdDesc(aSession);
@@ -368,16 +371,17 @@ VRDisplayOculus::VRDisplayOculus(ovrSess
mDisplayInfo.mCapabilityFlags = VRDisplayCapabilityFlags::Cap_None;
if (mDesc.AvailableTrackingCaps & ovrTrackingCap_Orientation) {
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Orientation;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_AngularAcceleration;
}
if (mDesc.AvailableTrackingCaps & ovrTrackingCap_Position) {
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Position;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_LinearAcceleration;
+ mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_StageParameters;
}
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_External;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_MountDetection;
mDisplayInfo.mCapabilityFlags |= VRDisplayCapabilityFlags::Cap_Present;
mFOVPort[VRDisplayInfo::Eye_Left] = mDesc.DefaultEyeFov[ovrEye_Left];
mFOVPort[VRDisplayInfo::Eye_Right] = mDesc.DefaultEyeFov[ovrEye_Right];
@@ -396,16 +400,18 @@ VRDisplayOculus::VRDisplayOculus(ovrSess
mDisplayInfo.mEyeTranslation[eye] = Point3D(renderDesc.HmdToEyeOffset.x, renderDesc.HmdToEyeOffset.y, renderDesc.HmdToEyeOffset.z);
texSize[eye] = ovr_GetFovTextureSize(mSession, (ovrEyeType)eye, mFOVPort[eye], pixelsPerDisplayPixel);
}
// take the max of both for eye resolution
mDisplayInfo.mEyeResolution.width = std::max(texSize[VRDisplayInfo::Eye_Left].w, texSize[VRDisplayInfo::Eye_Right].w);
mDisplayInfo.mEyeResolution.height = std::max(texSize[VRDisplayInfo::Eye_Left].h, texSize[VRDisplayInfo::Eye_Right].h);
+
+ UpdateStageParameters();
}
VRDisplayOculus::~VRDisplayOculus() {
StopPresentation();
Destroy();
MOZ_COUNT_DTOR_INHERITED(VRDisplayOculus, VRDisplayHost);
}
@@ -414,19 +420,58 @@ VRDisplayOculus::Destroy()
{
if (mSession) {
ovr_Destroy(mSession);
mSession = nullptr;
}
}
void
+VRDisplayOculus::UpdateStageParameters()
+{
+ ovrVector3f playArea;
+ ovrResult res = ovr_GetBoundaryDimensions(mSession, ovrBoundary_PlayArea, &playArea);
+ if (res == ovrSuccess) {
+ mDisplayInfo.mStageSize.width = playArea.x;
+ mDisplayInfo.mStageSize.height = playArea.z;
+ } else {
+ // If we fail, fall back to reasonable defaults.
+ // 1m x 1m space
+ mDisplayInfo.mStageSize.width = 1.0f;
+ mDisplayInfo.mStageSize.height = 1.0f;
+ }
+
+ mEyeHeight = ovr_GetFloat(mSession, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT);
+
+ mDisplayInfo.mSittingToStandingTransform._11 = 1.0f;
+ mDisplayInfo.mSittingToStandingTransform._12 = 0.0f;
+ mDisplayInfo.mSittingToStandingTransform._13 = 0.0f;
+ mDisplayInfo.mSittingToStandingTransform._14 = 0.0f;
+
+ mDisplayInfo.mSittingToStandingTransform._21 = 0.0f;
+ mDisplayInfo.mSittingToStandingTransform._22 = 1.0f;
+ mDisplayInfo.mSittingToStandingTransform._23 = 0.0f;
+ mDisplayInfo.mSittingToStandingTransform._24 = 0.0f;
+
+ mDisplayInfo.mSittingToStandingTransform._31 = 0.0f;
+ mDisplayInfo.mSittingToStandingTransform._32 = 0.0f;
+ mDisplayInfo.mSittingToStandingTransform._33 = 1.0f;
+ mDisplayInfo.mSittingToStandingTransform._34 = 0.0f;
+
+ mDisplayInfo.mSittingToStandingTransform._41 = 0.0f;
+ mDisplayInfo.mSittingToStandingTransform._42 = mEyeHeight;
+ mDisplayInfo.mSittingToStandingTransform._43 = 0.0f;
+ mDisplayInfo.mSittingToStandingTransform._44 = 1.0f;
+}
+
+void
VRDisplayOculus::ZeroSensor()
{
ovr_RecenterTrackingOrigin(mSession);
+ UpdateStageParameters();
}
VRHMDSensorState
VRDisplayOculus::GetSensorState()
{
mInputFrameID++;
VRHMDSensorState result;
@@ -435,16 +480,17 @@ VRDisplayOculus::GetSensorState()
// XXX We might need to call ovr_GetPredictedDisplayTime even if we don't use the result.
// If we don't call it, the Oculus driver will spew out many warnings...
double predictedFrameTime = ovr_GetPredictedDisplayTime(mSession, mInputFrameID);
frameDelta = predictedFrameTime - ovr_GetTimeInSeconds();
}
result = GetSensorState(frameDelta);
result.inputFrameID = mInputFrameID;
mLastSensorState[result.inputFrameID % kMaxLatencyFrames] = result;
+ result.position[1] -= mEyeHeight;
return result;
}
VRHMDSensorState
VRDisplayOculus::GetSensorState(double timeOffset)
{
VRHMDSensorState result;
result.Clear();
@@ -983,16 +1029,21 @@ VRSystemManagerOculus::GetHMDs(nsTArray<
mHMDInfo = nullptr;
} else if (mHMDInfo == nullptr) {
// HMD Detected
ovrSession session;
ovrGraphicsLuid luid;
ovrResult orv = ovr_Create(&session, &luid);
if (orv == ovrSuccess) {
mSession = session;
+ orv = ovr_SetTrackingOriginType(session, ovrTrackingOrigin_FloorLevel);
+ if (orv != ovrSuccess) {
+ NS_WARNING("ovr_SetTrackingOriginType failed.\n");
+ }
+
mHMDInfo = new VRDisplayOculus(session);
}
}
if (mHMDInfo) {
aHMDResult.AppendElement(mHMDInfo);
}
}
@@ -1094,16 +1145,19 @@ VRSystemManagerOculus::HandleInput()
poseState.linearVelocity[0] = pose.LinearVelocity.x;
poseState.linearVelocity[1] = pose.LinearVelocity.y;
poseState.linearVelocity[2] = pose.LinearVelocity.z;
poseState.flags |= GamepadCapabilityFlags::Cap_LinearAcceleration;
poseState.linearAcceleration[0] = pose.LinearAcceleration.x;
poseState.linearAcceleration[1] = pose.LinearAcceleration.y;
poseState.linearAcceleration[2] = pose.LinearAcceleration.z;
+
+ float eyeHeight = ovr_GetFloat(mSession, OVR_KEY_EYE_HEIGHT, OVR_DEFAULT_EYE_HEIGHT);
+ poseState.position[1] -= eyeHeight;
}
HandlePoseTracking(i, poseState, controller);
}
}
void
VRSystemManagerOculus::HandleButtonPress(uint32_t aControllerIdx,
uint32_t aButton,
--- a/gfx/vr/gfxVROculus.h
+++ b/gfx/vr/gfxVROculus.h
@@ -43,16 +43,17 @@ public:
protected:
virtual void StartPresentation() override;
virtual void StopPresentation() override;
virtual void SubmitFrame(mozilla::layers::TextureSourceD3D11* aSource,
const IntSize& aSize,
const VRHMDSensorState& aSensorState,
const gfx::Rect& aLeftEyeRect,
const gfx::Rect& aRightEyeRect) override;
+ void UpdateStageParameters();
public:
explicit VRDisplayOculus(ovrSession aSession);
protected:
virtual ~VRDisplayOculus();
void Destroy();
@@ -77,17 +78,18 @@ protected:
layers::VertexShaderConstants mVSConstants;
layers::PixelShaderConstants mPSConstants;
RefPtr<ID3D11Buffer> mVSConstantBuffer;
RefPtr<ID3D11Buffer> mPSConstantBuffer;
RefPtr<ID3D11Buffer> mVertexBuffer;
RefPtr<ID3D11InputLayout> mInputLayout;
bool mIsPresenting;
-
+ float mEyeHeight;
+
bool UpdateConstantBuffers();
struct Vertex
{
float position[2];
};
};
--- a/gfx/vr/ovr_capi_dynamic.h
+++ b/gfx/vr/ovr_capi_dynamic.h
@@ -562,32 +562,40 @@ typedef enum {
ovrDebugHudStereo_Off = 0,
ovrDebugHudStereo_Quad = 1,
ovrDebugHudStereo_QuadWithCrosshair = 2,
ovrDebugHudStereo_CrosshairAtInfinity = 3,
ovrDebugHudStereo_Count,
ovrDebugHudStereo_EnumSize = 0x7fffffff
} ovrDebugHudStereoMode;
+typedef enum {
+ // Outer boundary - closely represents user setup walls
+ ovrBoundary_Outer = 0x0001,
+ // Play area - safe rectangular area inside outer boundary which can optionally be used to restrict user interactions and motion.
+ ovrBoundary_PlayArea = 0x0100,
+} ovrBoundaryType;
+
typedef ovrBool(OVR_PFN* pfn_ovr_GetBool)(ovrSession session, const char* propertyName, ovrBool defaultVal);
-typedef ovrBool(OVR_PFN* pfn_ovr_SetBool)(ovrSession session, const char* propertyName, ovrBool value);
+typedef ovrBool(OVR_PFN* pfn_ovr_SetBool)(ovrSession session, const char* propertyName, ovrBool value);
typedef int (OVR_PFN* pfn_ovr_GetInt)(ovrSession session, const char* propertyName, int defaultVal);
typedef ovrBool (OVR_PFN* pfn_ovr_SetInt)(ovrSession session, const char* propertyName, int value);
typedef float (OVR_PFN* pfn_ovr_GetFloat)(ovrSession session, const char* propertyName, float defaultVal);
typedef ovrBool (OVR_PFN* pfn_ovr_SetFloat)(ovrSession session, const char* propertyName, float value);
typedef unsigned int (OVR_PFN* pfn_ovr_GetFloatArray)(ovrSession session, const char* propertyName,
float values[], unsigned int valuesCapacity);
typedef ovrBool (OVR_PFN* pfn_ovr_SetFloatArray)(ovrSession session, const char* propertyName,
const float values[], unsigned int valuesSize);
typedef const char* (OVR_PFN* pfn_ovr_GetString)(ovrSession session, const char* propertyName,
const char* defaultVal);
typedef ovrBool (OVR_PFN* pfn_ovr_SetString)(ovrSession session, const char* propertyName,
const char* value);
-
-
+typedef ovrResult (OVR_PFN* pfn_ovr_GetBoundaryDimensions)(ovrSession session,
+ ovrBoundaryType boundaryType,
+ ovrVector3f* outDimensions);
typedef enum {
ovrError_MemoryAllocationFailure = -1000,
ovrError_SocketCreationFailure = -1001,
ovrError_InvalidSession = -1002,
ovrError_Timeout = -1003,
ovrError_NotInitialized = -1004,
ovrError_InvalidParameter = -1005,
@@ -709,14 +717,17 @@ typedef ovrResult (OVR_PFN* pfn_ovr_GetT
typedef ovrResult (OVR_PFN* pfn_ovr_CreateMirrorTextureGL)(ovrSession session,
const ovrMirrorTextureDesc* desc,
ovrMirrorTexture* out_MirrorTexture);
typedef ovrResult (OVR_PFN* pfn_ovr_GetMirrorTextureBufferGL)(ovrSession session,
ovrMirrorTexture mirrorTexture,
unsigned int* out_TexId);
-#ifdef __cplusplus
+#define OVR_KEY_EYE_HEIGHT "EyeHeight" // float meters
+#define OVR_DEFAULT_EYE_HEIGHT 1.675f
+
+#ifdef __cplusplus
}
#endif
#endif /* mozilla_ovr_capi_dynamic_h_ */
#endif /* OVR_CAPI_h */