mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1410493 - Update Oculus SDK from 1.5 to 1.9, update IPD during VR presentation r=daoshengmu
- Oculus SDK was updated from 1.5 to 1.9 - As the Oculus API now returns quaternion orientations for each eye-to-head transform, I needed to send more information to the content process. - Rather than adding the quaternion, we now calculate the view matrices on the VR thread in the GPU process rather than calculating it in the content thread from parameters. - OpenVR's full view matrix is now used, for compatibility with more devices. - IPD adjustments are now updated every frame for both Oculus and OpenVR. MozReview-Commit-ID: LOtfs4QIqc8 --HG-- extra : rebase_source : 0a69824012ede4bea0e0e709a2d027d0c35730bb
This commit is contained in:
parent
4b8f90917d
commit
ccc6462307
@ -903,29 +903,6 @@ VRFrameInfo::Update(const gfx::VRDisplayInfo& aInfo,
|
||||
}
|
||||
mVRState.timestamp = aState.timestamp + mTimeStampOffset;
|
||||
|
||||
gfx::Quaternion qt;
|
||||
if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
|
||||
qt.x = mVRState.orientation[0];
|
||||
qt.y = mVRState.orientation[1];
|
||||
qt.z = mVRState.orientation[2];
|
||||
qt.w = mVRState.orientation[3];
|
||||
}
|
||||
gfx::Point3D pos;
|
||||
if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
|
||||
pos.x = -mVRState.position[0];
|
||||
pos.y = -mVRState.position[1];
|
||||
pos.z = -mVRState.position[2];
|
||||
}
|
||||
gfx::Matrix4x4 matHead;
|
||||
matHead.SetRotationFromQuaternion(qt);
|
||||
matHead.PreTranslate(pos);
|
||||
|
||||
mLeftView = matHead;
|
||||
mLeftView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Left]);
|
||||
|
||||
mRightView = matHead;
|
||||
mRightView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Right]);
|
||||
|
||||
// Avoid division by zero within ConstructProjectionMatrix
|
||||
const float kEpsilon = 0.00001f;
|
||||
if (fabs(aDepthFar - aDepthNear) < kEpsilon) {
|
||||
@ -936,6 +913,8 @@ VRFrameInfo::Update(const gfx::VRDisplayInfo& aInfo,
|
||||
mLeftProjection = leftFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
|
||||
const gfx::VRFieldOfView rightFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Right];
|
||||
mRightProjection = rightFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
|
||||
memcpy(mLeftView.components, aState.leftViewMatrix, sizeof(aState.leftViewMatrix));
|
||||
memcpy(mRightView.components, aState.rightViewMatrix, sizeof(aState.rightViewMatrix));
|
||||
}
|
||||
|
||||
VRFrameInfo::VRFrameInfo()
|
||||
|
@ -1437,6 +1437,59 @@ public:
|
||||
*((&_41)+aIndex) = aVector.w;
|
||||
}
|
||||
|
||||
bool Decompose(Point3D& translation, Quaternion& rotation, Point3D& scale) const
|
||||
{
|
||||
// Ensure matrix can be normalized
|
||||
if (gfx::FuzzyEqual(_44, 0.0f)) {
|
||||
return false;
|
||||
}
|
||||
Matrix4x4Typed mat = *this;
|
||||
mat.Normalize();
|
||||
if (HasPerspectiveComponent()) {
|
||||
// We do not support projection matrices
|
||||
return false;
|
||||
}
|
||||
|
||||
// Extract translation
|
||||
translation.x = mat._41;
|
||||
translation.y = mat._42;
|
||||
translation.z = mat._43;
|
||||
|
||||
// Remove translation
|
||||
mat._41 = 0.0f;
|
||||
mat._42 = 0.0f;
|
||||
mat._43 = 0.0f;
|
||||
|
||||
// Extract scale
|
||||
scale.x = sqrtf(_11 * _11 + _21 * _21 + _31 * _31);
|
||||
scale.y = sqrtf(_12 * _12 + _22 * _22 + _32 * _32);
|
||||
scale.z = sqrtf(_13 * _13 + _23 * _23 + _33 * _33);
|
||||
|
||||
// Remove scale
|
||||
if (gfx::FuzzyEqual(scale.x, 0.0f) ||
|
||||
gfx::FuzzyEqual(scale.y, 0.0f) ||
|
||||
gfx::FuzzyEqual(scale.z, 0.0f)) {
|
||||
// We do not support matrices with a zero scale component
|
||||
return false;
|
||||
}
|
||||
Float invXS = 1.0f / scale.x;
|
||||
Float invYS = 1.0f / scale.y;
|
||||
Float invZS = 1.0f / scale.z;
|
||||
mat._11 *= invXS;
|
||||
mat._21 *= invXS;
|
||||
mat._31 *= invXS;
|
||||
mat._12 *= invYS;
|
||||
mat._22 *= invYS;
|
||||
mat._32 *= invYS;
|
||||
mat._13 *= invZS;
|
||||
mat._23 *= invZS;
|
||||
mat._33 *= invZS;
|
||||
|
||||
// Extract rotation
|
||||
rotation.SetFromRotationMatrix(mat);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Sets this matrix to a rotation matrix given by aQuat.
|
||||
// This quaternion *MUST* be normalized!
|
||||
// Implemented in Quaternion.cpp
|
||||
|
@ -130,3 +130,21 @@ VRSystemManager::NewHandChangeEvent(uint32_t aIndex,
|
||||
vm->NotifyGamepadChange<dom::GamepadHandInformation>(aIndex, a);
|
||||
}
|
||||
|
||||
void
|
||||
VRHMDSensorState::CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms)
|
||||
{
|
||||
|
||||
gfx::Matrix4x4 matHead;
|
||||
if (flags & VRDisplayCapabilityFlags::Cap_Orientation) {
|
||||
matHead.SetRotationFromQuaternion(gfx::Quaternion(orientation[0], orientation[1],
|
||||
orientation[2], orientation[3]));
|
||||
}
|
||||
matHead.PreTranslate(-position[0], -position[1], -position[2]);
|
||||
|
||||
gfx::Matrix4x4 matView = matHead * aHeadToEyeTransforms[VRDisplayInfo::Eye_Left];
|
||||
matView.Normalize();
|
||||
memcpy(leftViewMatrix, matView.components, sizeof(matView.components));
|
||||
matView = matHead * aHeadToEyeTransforms[VRDisplayInfo::Eye_Right];
|
||||
matView.Normalize();
|
||||
memcpy(rightViewMatrix, matView.components, sizeof(matView.components));
|
||||
}
|
||||
|
@ -145,6 +145,8 @@ struct VRHMDSensorState {
|
||||
// These members will only change with inputFrameID:
|
||||
float orientation[4];
|
||||
float position[3];
|
||||
float leftViewMatrix[16];
|
||||
float rightViewMatrix[16];
|
||||
float angularVelocity[3];
|
||||
float angularAcceleration[3];
|
||||
float linearVelocity[3];
|
||||
@ -162,6 +164,7 @@ struct VRHMDSensorState {
|
||||
bool operator!=(const VRHMDSensorState& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
void CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms);
|
||||
};
|
||||
|
||||
// The maximum number of frames of latency that we would expect before we
|
||||
|
@ -261,6 +261,15 @@ VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
|
||||
mDisplayInfo.mEyeTranslation[eye].x = eyePose.translation.data[0];
|
||||
mDisplayInfo.mEyeTranslation[eye].y = eyePose.translation.data[1];
|
||||
mDisplayInfo.mEyeTranslation[eye].z = eyePose.translation.data[2];
|
||||
|
||||
Matrix4x4 pose;
|
||||
pose.SetRotationFromQuaternion(gfx::Quaternion(osvrQuatGetX(&eyePose.rotation),
|
||||
osvrQuatGetY(&eyePose.rotation),
|
||||
osvrQuatGetZ(&eyePose.rotation),
|
||||
osvrQuatGetW(&eyePose.rotation)));
|
||||
pose.PreTranslate(eyePose.translation.data[0], eyePose.translation.data[1], eyePose.translation.data[2]);
|
||||
pose.Invert();
|
||||
mHeadToEye[eye] = pose;
|
||||
}
|
||||
}
|
||||
|
||||
@ -305,6 +314,9 @@ VRDisplayOSVR::GetSensorState()
|
||||
result.orientation[1] = orientation.data[2];
|
||||
result.orientation[2] = orientation.data[3];
|
||||
result.orientation[3] = orientation.data[0];
|
||||
} else {
|
||||
// default to an identity quaternion
|
||||
result.orientation[3] = 1.0f;
|
||||
}
|
||||
|
||||
OSVR_PositionState position;
|
||||
@ -316,6 +328,8 @@ VRDisplayOSVR::GetSensorState()
|
||||
result.position[2] = position.data[2];
|
||||
}
|
||||
|
||||
result.CalcViewMatrices(mHeadToEye);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -64,6 +64,8 @@ protected:
|
||||
OSVR_ClientContext* m_ctx;
|
||||
OSVR_ClientInterface* m_iface;
|
||||
OSVR_DisplayConfig* m_display;
|
||||
|
||||
gfx::Matrix4x4 mHeadToEye[2];
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
|
@ -75,6 +75,8 @@ static pfn_ovr_GetTrackerDesc ovr_GetTrackerDesc = nullptr;
|
||||
static pfn_ovr_Create ovr_Create = nullptr;
|
||||
static pfn_ovr_Destroy ovr_Destroy = nullptr;
|
||||
static pfn_ovr_GetSessionStatus ovr_GetSessionStatus = nullptr;
|
||||
static pfn_ovr_IsExtensionSupported ovr_IsExtensionSupported = nullptr;
|
||||
static pfn_ovr_EnableExtension ovr_EnableExtension = nullptr;
|
||||
static pfn_ovr_SetTrackingOriginType ovr_SetTrackingOriginType = nullptr;
|
||||
static pfn_ovr_GetTrackingOriginType ovr_GetTrackingOriginType = nullptr;
|
||||
static pfn_ovr_RecenterTrackingOrigin ovr_RecenterTrackingOrigin = nullptr;
|
||||
@ -104,7 +106,10 @@ static pfn_ovr_CommitTextureSwapChain ovr_CommitTextureSwapChain = nullptr;
|
||||
static pfn_ovr_DestroyTextureSwapChain ovr_DestroyTextureSwapChain = nullptr;
|
||||
static pfn_ovr_DestroyMirrorTexture ovr_DestroyMirrorTexture = nullptr;
|
||||
static pfn_ovr_GetFovTextureSize ovr_GetFovTextureSize = nullptr;
|
||||
static pfn_ovr_GetRenderDesc ovr_GetRenderDesc = nullptr;
|
||||
static pfn_ovr_GetRenderDesc2 ovr_GetRenderDesc2 = nullptr;
|
||||
static pfn_ovr_WaitToBeginFrame ovr_WaitToBeginFrame = nullptr;
|
||||
static pfn_ovr_BeginFrame ovr_BeginFrame = nullptr;
|
||||
static pfn_ovr_EndFrame ovr_EndFrame = nullptr;
|
||||
static pfn_ovr_SubmitFrame ovr_SubmitFrame = nullptr;
|
||||
static pfn_ovr_GetPerfStats ovr_GetPerfStats = nullptr;
|
||||
static pfn_ovr_ResetPerfStats ovr_ResetPerfStats = nullptr;
|
||||
@ -143,7 +148,7 @@ static pfn_ovr_GetMirrorTextureBufferGL ovr_GetMirrorTextureBufferGL = nullptr;
|
||||
|
||||
#define OVR_PRODUCT_VERSION 1
|
||||
#define OVR_MAJOR_VERSION 1
|
||||
#define OVR_MINOR_VERSION 15
|
||||
#define OVR_MINOR_VERSION 19
|
||||
|
||||
enum class OculusLeftControllerButtonType : uint16_t {
|
||||
LThumb,
|
||||
@ -635,6 +640,8 @@ VROculusSession::LoadOvrLib()
|
||||
REQUIRE_FUNCTION(ovr_Create);
|
||||
REQUIRE_FUNCTION(ovr_Destroy);
|
||||
REQUIRE_FUNCTION(ovr_GetSessionStatus);
|
||||
REQUIRE_FUNCTION(ovr_IsExtensionSupported);
|
||||
REQUIRE_FUNCTION(ovr_EnableExtension);
|
||||
REQUIRE_FUNCTION(ovr_SetTrackingOriginType);
|
||||
REQUIRE_FUNCTION(ovr_GetTrackingOriginType);
|
||||
REQUIRE_FUNCTION(ovr_RecenterTrackingOrigin);
|
||||
@ -664,7 +671,10 @@ VROculusSession::LoadOvrLib()
|
||||
REQUIRE_FUNCTION(ovr_DestroyTextureSwapChain);
|
||||
REQUIRE_FUNCTION(ovr_DestroyMirrorTexture);
|
||||
REQUIRE_FUNCTION(ovr_GetFovTextureSize);
|
||||
REQUIRE_FUNCTION(ovr_GetRenderDesc);
|
||||
REQUIRE_FUNCTION(ovr_GetRenderDesc2);
|
||||
REQUIRE_FUNCTION(ovr_WaitToBeginFrame);
|
||||
REQUIRE_FUNCTION(ovr_BeginFrame);
|
||||
REQUIRE_FUNCTION(ovr_EndFrame);
|
||||
REQUIRE_FUNCTION(ovr_SubmitFrame);
|
||||
REQUIRE_FUNCTION(ovr_GetPerfStats);
|
||||
REQUIRE_FUNCTION(ovr_ResetPerfStats);
|
||||
@ -779,14 +789,8 @@ VRDisplayOculus::VRDisplayOculus(VROculusSession* aSession)
|
||||
float pixelsPerDisplayPixel = 1.0;
|
||||
ovrSizei texSize[2];
|
||||
|
||||
// get eye parameters and create the mesh
|
||||
// get eye texture sizes
|
||||
for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
|
||||
|
||||
ovrEyeRenderDesc renderDesc = ovr_GetRenderDesc(mSession->Get(), (ovrEyeType)eye, mFOVPort[eye]);
|
||||
|
||||
// As of Oculus 0.6.0, the HmdToEyeOffset values are correct and don't need to be negated.
|
||||
mDisplayInfo.mEyeTranslation[eye] = Point3D(renderDesc.HmdToEyeOffset.x, renderDesc.HmdToEyeOffset.y, renderDesc.HmdToEyeOffset.z);
|
||||
|
||||
texSize[eye] = ovr_GetFovTextureSize(mSession->Get(), (ovrEyeType)eye, mFOVPort[eye], pixelsPerDisplayPixel);
|
||||
}
|
||||
|
||||
@ -794,6 +798,7 @@ VRDisplayOculus::VRDisplayOculus(VROculusSession* aSession)
|
||||
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);
|
||||
|
||||
UpdateEyeParameters();
|
||||
UpdateStageParameters();
|
||||
}
|
||||
|
||||
@ -809,6 +814,29 @@ VRDisplayOculus::Destroy()
|
||||
mSession = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayOculus::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = nullptr */)
|
||||
{
|
||||
// Note this must be called every frame, as the IPD adjustment can be changed
|
||||
// by the user during a VR session.
|
||||
for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
|
||||
// As of Oculus 1.17 SDK, we must use the ovr_GetRenderDesc2 function to return the updated
|
||||
// version of ovrEyeRenderDesc. This is normally done by the Oculus static lib shim, but we
|
||||
// need to do this explicitly as we are loading the Oculus runtime dll directly.
|
||||
ovrEyeRenderDesc renderDesc = ovr_GetRenderDesc2(mSession->Get(), (ovrEyeType)eye, mFOVPort[eye]);
|
||||
mDisplayInfo.mEyeTranslation[eye].x = renderDesc.HmdToEyePose.Position.x;
|
||||
mDisplayInfo.mEyeTranslation[eye].y = renderDesc.HmdToEyePose.Position.y;
|
||||
mDisplayInfo.mEyeTranslation[eye].z = renderDesc.HmdToEyePose.Position.z;
|
||||
if (aHeadToEyeTransforms) {
|
||||
Matrix4x4 pose;
|
||||
pose.SetRotationFromQuaternion(gfx::Quaternion(renderDesc.HmdToEyePose.Orientation.x, renderDesc.HmdToEyePose.Orientation.y, renderDesc.HmdToEyePose.Orientation.z, renderDesc.HmdToEyePose.Orientation.w));
|
||||
pose.PreTranslate(renderDesc.HmdToEyePose.Position.x, renderDesc.HmdToEyePose.Position.y, renderDesc.HmdToEyePose.Position.z);
|
||||
pose.Invert();
|
||||
aHeadToEyeTransforms[eye] = pose;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayOculus::UpdateStageParameters()
|
||||
{
|
||||
@ -865,6 +893,8 @@ VRDisplayOculus::GetSensorState()
|
||||
{
|
||||
VRHMDSensorState result;
|
||||
if (mSession->IsTrackingReady()) {
|
||||
gfx::Matrix4x4 headToEyeTransforms[2];
|
||||
UpdateEyeParameters(headToEyeTransforms);
|
||||
double predictedFrameTime = 0.0f;
|
||||
if (gfxPrefs::VRPosePredictionEnabled()) {
|
||||
// XXX We might need to call ovr_GetPredictedDisplayTime even if we don't use the result.
|
||||
@ -872,10 +902,11 @@ VRDisplayOculus::GetSensorState()
|
||||
predictedFrameTime = ovr_GetPredictedDisplayTime(mSession->Get(), 0);
|
||||
}
|
||||
result = GetSensorState(predictedFrameTime);
|
||||
result.position[1] -= mEyeHeight;
|
||||
result.CalcViewMatrices(headToEyeTransforms);
|
||||
}
|
||||
result.inputFrameID = mDisplayInfo.mFrameId;
|
||||
result.position[1] -= mEyeHeight;
|
||||
mDisplayInfo.mLastSensorState[result.inputFrameID % kVRMaxLatencyFrames] = result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -906,6 +937,9 @@ VRDisplayOculus::GetSensorState(double absTime)
|
||||
result.angularAcceleration[0] = pose.AngularAcceleration.x;
|
||||
result.angularAcceleration[1] = pose.AngularAcceleration.y;
|
||||
result.angularAcceleration[2] = pose.AngularAcceleration.z;
|
||||
} else {
|
||||
// default to an identity quaternion
|
||||
result.orientation[3] = 1.0f;
|
||||
}
|
||||
|
||||
if (state.StatusFlags & ovrStatus_PositionTracked) {
|
||||
@ -1172,27 +1206,25 @@ VRDisplayOculus::SubmitFrame(ID3D11Texture2D* aSource,
|
||||
layer.Viewport[1].Size.w = aSize.width * aRightEyeRect.Width();
|
||||
layer.Viewport[1].Size.h = aSize.height * aRightEyeRect.Height();
|
||||
|
||||
const Point3D& l = mDisplayInfo.mEyeTranslation[0];
|
||||
const Point3D& r = mDisplayInfo.mEyeTranslation[1];
|
||||
const ovrVector3f hmdToEyeViewOffset[2] = { { l.x, l.y, l.z },
|
||||
{ r.x, r.y, r.z } };
|
||||
|
||||
const VRHMDSensorState& sensorState = mDisplayInfo.GetSensorState();
|
||||
gfx::Matrix4x4 matView[2];
|
||||
memcpy(matView[0].components, sensorState.leftViewMatrix, sizeof(sensorState.leftViewMatrix));
|
||||
memcpy(matView[1].components, sensorState.rightViewMatrix, sizeof(sensorState.rightViewMatrix));
|
||||
|
||||
for (uint32_t i = 0; i < 2; ++i) {
|
||||
Quaternion o(sensorState.orientation[0],
|
||||
sensorState.orientation[1],
|
||||
sensorState.orientation[2],
|
||||
sensorState.orientation[3]);
|
||||
Point3D vo(hmdToEyeViewOffset[i].x, hmdToEyeViewOffset[i].y, hmdToEyeViewOffset[i].z);
|
||||
Point3D p = o.RotatePoint(vo);
|
||||
layer.RenderPose[i].Orientation.x = o.x;
|
||||
layer.RenderPose[i].Orientation.y = o.y;
|
||||
layer.RenderPose[i].Orientation.z = o.z;
|
||||
layer.RenderPose[i].Orientation.w = o.w;
|
||||
layer.RenderPose[i].Position.x = p.x + sensorState.position[0];
|
||||
layer.RenderPose[i].Position.y = p.y + sensorState.position[1];
|
||||
layer.RenderPose[i].Position.z = p.z + sensorState.position[2];
|
||||
Point3D eyeTranslation;
|
||||
Quaternion eyeRotation;
|
||||
Point3D eyeScale;
|
||||
if (!matView[i].Decompose(eyeTranslation, eyeRotation, eyeScale)) {
|
||||
NS_WARNING("Failed to decompose eye pose matrix for Oculus");
|
||||
}
|
||||
layer.RenderPose[i].Orientation.x = eyeRotation.x;
|
||||
layer.RenderPose[i].Orientation.y = eyeRotation.y;
|
||||
layer.RenderPose[i].Orientation.z = eyeRotation.z;
|
||||
layer.RenderPose[i].Orientation.w = eyeRotation.w;
|
||||
layer.RenderPose[i].Position.x = eyeTranslation.x;
|
||||
layer.RenderPose[i].Position.y = eyeTranslation.y;
|
||||
layer.RenderPose[i].Position.z = eyeTranslation.z;
|
||||
}
|
||||
|
||||
ovrLayerHeader *layers = &layer.Header;
|
||||
|
@ -123,6 +123,7 @@ protected:
|
||||
float mEyeHeight;
|
||||
|
||||
bool UpdateConstantBuffers();
|
||||
void UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms = nullptr);
|
||||
|
||||
struct Vertex
|
||||
{
|
||||
|
@ -87,14 +87,8 @@ VRDisplayOpenVR::VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
|
||||
float l, r, t, b;
|
||||
mVRSystem->GetProjectionRaw(static_cast<::vr::Hmd_Eye>(eye), &l, &r, &t, &b);
|
||||
mDisplayInfo.mEyeFOV[eye].SetFromTanRadians(-t, r, b, -l);
|
||||
|
||||
::vr::HmdMatrix34_t eyeToHead = mVRSystem->GetEyeToHeadTransform(static_cast<::vr::Hmd_Eye>(eye));
|
||||
|
||||
mDisplayInfo.mEyeTranslation[eye].x = eyeToHead.m[0][3];
|
||||
mDisplayInfo.mEyeTranslation[eye].y = eyeToHead.m[1][3];
|
||||
mDisplayInfo.mEyeTranslation[eye].z = eyeToHead.m[2][3];
|
||||
}
|
||||
|
||||
UpdateEyeParameters();
|
||||
UpdateStageParameters();
|
||||
}
|
||||
|
||||
@ -111,6 +105,31 @@ VRDisplayOpenVR::Destroy()
|
||||
::vr::VR_Shutdown();
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayOpenVR::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = nullptr */)
|
||||
{
|
||||
// Note this must be called every frame, as the IPD adjustment can be changed
|
||||
// by the user during a VR session.
|
||||
for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
|
||||
::vr::HmdMatrix34_t eyeToHead = mVRSystem->GetEyeToHeadTransform(static_cast<::vr::Hmd_Eye>(eye));
|
||||
|
||||
mDisplayInfo.mEyeTranslation[eye].x = eyeToHead.m[0][3];
|
||||
mDisplayInfo.mEyeTranslation[eye].y = eyeToHead.m[1][3];
|
||||
mDisplayInfo.mEyeTranslation[eye].z = eyeToHead.m[2][3];
|
||||
|
||||
if (aHeadToEyeTransforms) {
|
||||
Matrix4x4 pose;
|
||||
// NOTE! eyeToHead.m is a 3x4 matrix, not 4x4. But
|
||||
// because of its arrangement, we can copy the 12 elements in and
|
||||
// then transpose them to the right place.
|
||||
memcpy(&pose._11, &eyeToHead.m, sizeof(eyeToHead.m));
|
||||
pose.Transpose();
|
||||
pose.Invert();
|
||||
aHeadToEyeTransforms[eye] = pose;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VRDisplayOpenVR::UpdateStageParameters()
|
||||
{
|
||||
@ -231,6 +250,8 @@ VRDisplayOpenVR::GetSensorState()
|
||||
::vr::TrackedDevicePose_t poses[posesSize];
|
||||
// Note: We *must* call WaitGetPoses in order for any rendering to happen at all.
|
||||
mVRCompositor->WaitGetPoses(nullptr, 0, poses, posesSize);
|
||||
gfx::Matrix4x4 headToEyeTransforms[2];
|
||||
UpdateEyeParameters(headToEyeTransforms);
|
||||
|
||||
VRHMDSensorState result;
|
||||
|
||||
@ -254,7 +275,7 @@ VRDisplayOpenVR::GetSensorState()
|
||||
// because of its arrangement, we can copy the 12 elements in and
|
||||
// then transpose them to the right place. We do this so we can
|
||||
// pull out a Quaternion.
|
||||
memcpy(&m._11, &pose.mDeviceToAbsoluteTracking, sizeof(float) * 12);
|
||||
memcpy(&m._11, &pose.mDeviceToAbsoluteTracking, sizeof(pose.mDeviceToAbsoluteTracking));
|
||||
m.Transpose();
|
||||
|
||||
gfx::Quaternion rot;
|
||||
@ -277,8 +298,12 @@ VRDisplayOpenVR::GetSensorState()
|
||||
result.linearVelocity[0] = pose.vVelocity.v[0];
|
||||
result.linearVelocity[1] = pose.vVelocity.v[1];
|
||||
result.linearVelocity[2] = pose.vVelocity.v[2];
|
||||
} else {
|
||||
// default to an identity quaternion
|
||||
result.orientation[3] = 1.0f;
|
||||
}
|
||||
|
||||
result.CalcViewMatrices(headToEyeTransforms);
|
||||
result.inputFrameID = mDisplayInfo.mFrameId;
|
||||
return result;
|
||||
}
|
||||
@ -816,7 +841,7 @@ VRSystemManagerOpenVR::HandleInput()
|
||||
// because of its arrangement, we can copy the 12 elements in and
|
||||
// then transpose them to the right place. We do this so we can
|
||||
// pull out a Quaternion.
|
||||
memcpy(&m.components, &pose.mDeviceToAbsoluteTracking, sizeof(float) * 12);
|
||||
memcpy(&m.components, &pose.mDeviceToAbsoluteTracking, sizeof(pose.mDeviceToAbsoluteTracking));
|
||||
m.Transpose();
|
||||
|
||||
gfx::Quaternion rot;
|
||||
|
@ -69,6 +69,7 @@ protected:
|
||||
bool mIsHmdPresent;
|
||||
|
||||
void UpdateStageParameters();
|
||||
void UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms = nullptr);
|
||||
void PollEvents();
|
||||
bool SubmitFrame(void* aTextureHandle,
|
||||
::vr::ETextureType aTextureType,
|
||||
|
@ -150,6 +150,13 @@ VRHMDSensorState
|
||||
VRDisplayPuppet::GetSensorState()
|
||||
{
|
||||
mSensorState.inputFrameID = mDisplayInfo.mFrameId;
|
||||
|
||||
Matrix4x4 matHeadToEye[2];
|
||||
for (uint32_t eye = 0; eye < 2; ++eye) {
|
||||
matHeadToEye[eye].PreTranslate(mDisplayInfo.mEyeTranslation[eye]);
|
||||
}
|
||||
mSensorState.CalcViewMatrices(matHeadToEye);
|
||||
|
||||
return mSensorState;
|
||||
}
|
||||
|
||||
|
@ -115,6 +115,12 @@ struct ParamTraits<mozilla::gfx::VRHMDSensorState>
|
||||
WriteParam(aMsg, aParam.linearAcceleration[0]);
|
||||
WriteParam(aMsg, aParam.linearAcceleration[1]);
|
||||
WriteParam(aMsg, aParam.linearAcceleration[2]);
|
||||
for (int i=0; i < 16; i++) {
|
||||
WriteParam(aMsg, aParam.leftViewMatrix[i]);
|
||||
}
|
||||
for (int i=0; i < 16; i++) {
|
||||
WriteParam(aMsg, aParam.rightViewMatrix[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
@ -143,6 +149,16 @@ struct ParamTraits<mozilla::gfx::VRHMDSensorState>
|
||||
!ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) {
|
||||
return false;
|
||||
}
|
||||
for (int i=0; i < 16; i++) {
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->leftViewMatrix[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i=0; i < 16; i++) {
|
||||
if (!ReadParam(aMsg, aIter, &(aResult->rightViewMatrix[i]))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -126,6 +126,12 @@ typedef enum
|
||||
ovrTrackingCap_EnumSize = 0x7fffffff
|
||||
} ovrTrackingCaps;
|
||||
|
||||
typedef enum {
|
||||
ovrExtension_TextureLayout_Octilinear = 0,
|
||||
ovrExtension_Count,
|
||||
ovrExtension_EnumSize = 0x7fffffff
|
||||
} ovrExtensions;
|
||||
|
||||
typedef enum {
|
||||
ovrEye_Left = 0,
|
||||
ovrEye_Right = 1,
|
||||
@ -211,7 +217,7 @@ typedef struct OVR_ALIGNAS(4) {
|
||||
ovrFovPort Fov;
|
||||
ovrRecti DistortedViewport;
|
||||
ovrVector2f PixelsPerTanAngleAtCenter;
|
||||
ovrVector3f HmdToEyeOffset;
|
||||
ovrPosef HmdToEyePose;
|
||||
} ovrEyeRenderDesc;
|
||||
|
||||
typedef struct OVR_ALIGNAS(4) {
|
||||
@ -221,7 +227,7 @@ typedef struct OVR_ALIGNAS(4) {
|
||||
} ovrTimewarpProjectionDesc;
|
||||
|
||||
typedef struct OVR_ALIGNAS(4) {
|
||||
ovrVector3f HmdToEyeOffset[ovrEye_Count];
|
||||
ovrPosef HmdToEyePose[ovrEye_Count];
|
||||
float HmdSpaceToWorldScaleInMeters;
|
||||
} ovrViewScaleDesc;
|
||||
|
||||
@ -277,6 +283,7 @@ typedef enum {
|
||||
ovrTextureMisc_DX_Typeless = 0x0001,
|
||||
ovrTextureMisc_AllowGenerateMips = 0x0002,
|
||||
ovrTextureMisc_ProtectedContent = 0x0004,
|
||||
ovrTextureMisc_AutoGenerateMips = 0x0008,
|
||||
ovrTextureMisc_EnumSize = 0x7fffffff
|
||||
} ovrTextureFlags;
|
||||
|
||||
@ -378,6 +385,8 @@ typedef enum {
|
||||
ovrHapticsBufferSubmit_Enqueue
|
||||
} ovrHapticsBufferSubmitMode;
|
||||
|
||||
#define OVR_HAPTICS_BUFFER_SAMPLES_MAX 256
|
||||
|
||||
typedef struct {
|
||||
const void* Samples;
|
||||
int SamplesCount;
|
||||
@ -483,6 +492,7 @@ typedef enum {
|
||||
ovrInit_RequestVersion = 0x00000004,
|
||||
ovrInit_Invisible = 0x00000010,
|
||||
ovrInit_MixedRendering = 0x00000020,
|
||||
ovrInit_FocusAware = 0x00000040,
|
||||
ovrinit_WritableBits = 0x00ffffff,
|
||||
ovrInit_EnumSize = 0x7fffffff
|
||||
} ovrInitFlags;
|
||||
@ -530,9 +540,15 @@ typedef struct {
|
||||
ovrBool DisplayLost;
|
||||
ovrBool ShouldQuit;
|
||||
ovrBool ShouldRecenter;
|
||||
ovrBool HasInputFocus;
|
||||
ovrBool OverlayPresent;
|
||||
} ovrSessionStatus;
|
||||
|
||||
typedef ovrResult (OVR_PFN* pfn_ovr_GetSessionStatus)(ovrSession session, ovrSessionStatus* sessionStatus);
|
||||
typedef ovrResult (OVR_PFN* pfn_ovr_IsExtensionSupported)(ovrSession session,
|
||||
ovrExtensions extension,
|
||||
ovrBool* outExtensionSupported);
|
||||
typedef ovrResult (OVR_PFN* pfn_ovr_EnableExtension)(ovrSession session, ovrExtensions extension);
|
||||
typedef ovrResult (OVR_PFN* pfn_ovr_SetTrackingOriginType)(ovrSession session, ovrTrackingOrigin origin);
|
||||
typedef ovrTrackingOrigin (OVR_PFN* pfn_ovr_GetTrackingOriginType)(ovrSession session);
|
||||
typedef ovrResult (OVR_PFN* pfn_ovr_RecenterTrackingOrigin)(ovrSession session);
|
||||
@ -584,6 +600,8 @@ typedef enum {
|
||||
ovrLayerType_EyeFov = 1,
|
||||
ovrLayerType_Quad = 3,
|
||||
ovrLayerType_EyeMatrix = 5,
|
||||
ovrLayerType_EyeFovMultires = 7,
|
||||
ovrLayerType_Cube = 10,
|
||||
ovrLayerType_EnumSize = 0x7fffffff
|
||||
} ovrLayerType;
|
||||
|
||||
@ -607,6 +625,39 @@ typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
|
||||
double SensorSampleTime;
|
||||
} ovrLayerEyeFov;
|
||||
|
||||
typedef enum {
|
||||
ovrTextureLayout_Rectilinear = 0,
|
||||
ovrTextureLayout_Octilinear = 1,
|
||||
ovrTextureLayout_EnumSize = 0x7fffffff
|
||||
} ovrTextureLayout;
|
||||
|
||||
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
|
||||
float WarpLeft;
|
||||
float WarpRight;
|
||||
float WarpUp;
|
||||
float WarpDown;
|
||||
float SizeLeft;
|
||||
float SizeRight;
|
||||
float SizeUp;
|
||||
float SizeDown;
|
||||
|
||||
} ovrTextureLayoutOctilinear;
|
||||
|
||||
typedef union OVR_ALIGNAS(OVR_PTR_SIZE) {
|
||||
ovrTextureLayoutOctilinear Octilinear[ovrEye_Count];
|
||||
} ovrTextureLayoutDesc_Union;
|
||||
|
||||
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
|
||||
ovrLayerHeader Header;
|
||||
ovrTextureSwapChain ColorTexture[ovrEye_Count];
|
||||
ovrRecti Viewport[ovrEye_Count];
|
||||
ovrFovPort Fov[ovrEye_Count];
|
||||
ovrPosef RenderPose[ovrEye_Count];
|
||||
double SensorSampleTime;
|
||||
ovrTextureLayout TextureLayout;
|
||||
ovrTextureLayoutDesc_Union TextureLayoutDesc;
|
||||
} ovrLayerEyeFovMultires;
|
||||
|
||||
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
|
||||
ovrLayerHeader Header;
|
||||
ovrTextureSwapChain ColorTexture[ovrEye_Count];
|
||||
@ -624,10 +675,18 @@ typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
|
||||
ovrVector2f QuadSize;
|
||||
} ovrLayerQuad;
|
||||
|
||||
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
|
||||
ovrLayerHeader Header;
|
||||
ovrQuatf Orientation;
|
||||
ovrTextureSwapChain CubeMapTexture;
|
||||
} ovrLayerCube;
|
||||
|
||||
typedef union {
|
||||
ovrLayerHeader Header;
|
||||
ovrLayerEyeFov EyeFov;
|
||||
ovrLayerQuad Quad;
|
||||
ovrLayerEyeFovMultires Multires;
|
||||
ovrLayerCube Cube;
|
||||
} ovrLayer_Union;
|
||||
|
||||
|
||||
@ -638,7 +697,14 @@ typedef ovrResult (OVR_PFN* pfn_ovr_CommitTextureSwapChain)(ovrSession session,
|
||||
typedef void (OVR_PFN* pfn_ovr_DestroyTextureSwapChain)(ovrSession session, ovrTextureSwapChain chain);
|
||||
typedef void (OVR_PFN* pfn_ovr_DestroyMirrorTexture)(ovrSession session, ovrMirrorTexture mirrorTexture);
|
||||
typedef ovrSizei(OVR_PFN* pfn_ovr_GetFovTextureSize)(ovrSession session, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel);
|
||||
typedef ovrEyeRenderDesc(OVR_PFN* pfn_ovr_GetRenderDesc)(ovrSession session, ovrEyeType eyeType, ovrFovPort fov);
|
||||
typedef ovrEyeRenderDesc(OVR_PFN* pfn_ovr_GetRenderDesc2)(ovrSession session, ovrEyeType eyeType, ovrFovPort fov);
|
||||
typedef ovrResult (OVR_PFN* pfn_ovr_WaitToBeginFrame)(ovrSession session, long long frameIndex);
|
||||
typedef ovrResult (OVR_PFN* pfn_ovr_BeginFrame)(ovrSession session, long long frameIndex);
|
||||
typedef ovrResult (OVR_PFN* pfn_ovr_EndFrame)(ovrSession session,
|
||||
long long frameIndex,
|
||||
const ovrViewScaleDesc* viewScaleDesc,
|
||||
ovrLayerHeader const* const* layerPtrList,
|
||||
unsigned int layerCount);
|
||||
typedef ovrResult(OVR_PFN* pfn_ovr_SubmitFrame)(ovrSession session, long long frameIndex,
|
||||
const ovrViewScaleDesc* viewScaleDesc,
|
||||
ovrLayerHeader const * const * layerPtrList, unsigned int layerCount);
|
||||
@ -753,6 +819,7 @@ typedef enum {
|
||||
ovrError_InvalidOperation = -1015,
|
||||
ovrError_InsufficientArraySize = -1016,
|
||||
ovrError_NoExternalCameraInfo = -1017,
|
||||
ovrError_LostTracking = -1018,
|
||||
ovrError_AudioDeviceNotFound = -2001,
|
||||
ovrError_AudioComError = -2002,
|
||||
ovrError_Initialize = -3000,
|
||||
|
Loading…
Reference in New Issue
Block a user