Skip to content

Commit

Permalink
Merge pull request #2 from Igalia/mortimer/eye_transform
Browse files Browse the repository at this point in the history
Use eye transform instead of translation in external_vr
  • Loading branch information
svillar authored Mar 17, 2022
2 parents b2c6065 + c6190d4 commit 82051b6
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 53 deletions.
36 changes: 12 additions & 24 deletions dom/vr/VRServiceTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,36 +95,24 @@ void VRMockDisplay::Create() {
state.eyeResolution.width = 1836; // 1080 * 1.7
state.eyeResolution.height = 2040; // 1200 * 1.7

float identity[16] = {
1.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f
};

for (uint32_t eye = 0; eye < VRDisplayState::NumEyes; ++eye) {
state.eyeTranslation[eye].x = 0.0f;
state.eyeTranslation[eye].y = 0.0f;
state.eyeTranslation[eye].z = 0.0f;
memcpy(state.eyeTransform[eye], identity, sizeof(identity));
state.eyeFOV[eye] = gfx::VRFieldOfView(45.0, 45.0, 45.0, 45.0);
}

// default: 1m x 1m space, 0.75m high in seated position
state.stageSize.width = 1.0f;
state.stageSize.height = 1.0f;

state.sittingToStandingTransform[0] = 1.0f;
state.sittingToStandingTransform[1] = 0.0f;
state.sittingToStandingTransform[2] = 0.0f;
state.sittingToStandingTransform[3] = 0.0f;

state.sittingToStandingTransform[4] = 0.0f;
state.sittingToStandingTransform[5] = 1.0f;
state.sittingToStandingTransform[6] = 0.0f;
state.sittingToStandingTransform[7] = 0.0f;

state.sittingToStandingTransform[8] = 0.0f;
state.sittingToStandingTransform[9] = 0.0f;
state.sittingToStandingTransform[10] = 1.0f;
state.sittingToStandingTransform[11] = 0.0f;

state.sittingToStandingTransform[12] = 0.0f;
memcpy(state.sittingToStandingTransform, identity, sizeof(identity));
state.sittingToStandingTransform[13] = 0.75f;
state.sittingToStandingTransform[14] = 0.0f;
state.sittingToStandingTransform[15] = 1.0f;

VRHMDSensorState& sensorState = SensorState();
gfx::Quaternion rot;
Expand Down Expand Up @@ -221,9 +209,9 @@ void VRMockDisplay::SetEyeOffset(VREye aEye, double aOffsetX, double aOffsetY,
? gfx::VRDisplayState::Eye_Left
: gfx::VRDisplayState::Eye_Right;
VRDisplayState& state = DisplayState();
state.eyeTranslation[eye].x = (float)aOffsetX;
state.eyeTranslation[eye].y = (float)aOffsetY;
state.eyeTranslation[eye].z = (float)aOffsetZ;
state.eyeTransform[eye][12] = (float)aOffsetX;
state.eyeTransform[eye][13] = (float)aOffsetY;
state.eyeTransform[eye][14] = (float)aOffsetZ;
}

bool VRMockDisplay::CapPosition() const {
Expand Down
17 changes: 5 additions & 12 deletions dom/vr/XRFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "mozilla/dom/XRView.h"
#include "mozilla/dom/XRReferenceSpace.h"
#include "VRDisplayClient.h"
#define VRB_ERROR(format, ...) __android_log_print(ANDROID_LOG_ERROR, "VRB", format, ##__VA_ARGS__);

namespace mozilla {
namespace dom {
Expand Down Expand Up @@ -89,20 +90,13 @@ already_AddRefed<XRViewerPose> XRFrame::GetViewerPose(
viewerPose = mSession->PooledViewerPose(headTransform, emulatedPosition);

auto updateEye = [&](int32_t viewIndex, gfx::VRDisplayState::Eye eye) {
auto offset = displayInfo.GetEyeTranslation(eye);
auto eyeFromHead = gfx::Matrix4x4Double::Translation(
gfx::PointDouble3D(offset.x, offset.y, offset.z));
auto eyeTransform = eyeFromHead * headTransform;
gfx::PointDouble3D eyePosition;
gfx::QuaternionDouble eyeRotation;
gfx::PointDouble3D eyeScale;
eyeTransform.Decompose(eyePosition, eyeRotation, eyeScale);
auto eyeFromHead = displayInfo.GetEyeTransform(eye);
auto viewTransform = eyeFromHead * headTransform;

const gfx::VRFieldOfView fov = displayInfo.mDisplayState.eyeFOV[eye];
gfx::Matrix4x4 projection =
fov.ConstructProjectionMatrix(depthNear, depthFar, true);
viewerPose->GetEye(viewIndex)->Update(eyePosition, eyeRotation,
projection);
viewerPose->GetEye(viewIndex)->Update(viewTransform, projection);
};

updateEye(0, gfx::VRDisplayState::Eye_Left);
Expand All @@ -121,8 +115,7 @@ already_AddRefed<XRViewerPose> XRFrame::GetViewerPose(

viewerPose =
mSession->PooledViewerPose(gfx::Matrix4x4Double(), emulatedPosition);
viewerPose->GetEye(0)->Update(gfx::PointDouble3D(), gfx::QuaternionDouble(),
projection);
viewerPose->GetEye(0)->Update(gfx::Matrix4x4Double(), projection);
}

return viewerPose.forget();
Expand Down
13 changes: 5 additions & 8 deletions dom/vr/XRView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,7 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(XRView, Release)
XRView::XRView(nsISupports* aParent, const XREye& aEye)
: mParent(aParent),
mEye(aEye),
mPosition(gfx::PointDouble3D()),
mOrientation(gfx::QuaternionDouble()),
mEyeTransform(gfx::Matrix4x4Double()),
mJSProjectionMatrix(nullptr) {
mozilla::HoldJSObjects(this);
}
Expand All @@ -49,14 +48,12 @@ JSObject* XRView::WrapObject(JSContext* aCx,
return XRView_Binding::Wrap(aCx, this, aGivenProto);
}

void XRView::Update(const gfx::PointDouble3D& aPosition,
const gfx::QuaternionDouble& aOrientation,
void XRView::Update(const gfx::Matrix4x4Double& aEyeTransform,
const gfx::Matrix4x4& aProjectionMatrix) {
mPosition = aPosition;
mOrientation = aOrientation;
mEyeTransform = aEyeTransform;
mProjectionMatrix = aProjectionMatrix;
if (mTransform) {
mTransform->Update(aPosition, aOrientation);
mTransform->Update(mEyeTransform);
}
if (aProjectionMatrix != mProjectionMatrix) {
mProjectionNeedsUpdate = true;
Expand Down Expand Up @@ -87,7 +84,7 @@ void XRView::GetProjectionMatrix(JSContext* aCx,

already_AddRefed<XRRigidTransform> XRView::GetTransform(ErrorResult& aRv) {
if (!mTransform) {
mTransform = new XRRigidTransform(mParent, mPosition, mOrientation);
mTransform = new XRRigidTransform(mParent, mEyeTransform);
}
RefPtr<XRRigidTransform> transform = mTransform;
return transform.forget();
Expand Down
6 changes: 2 additions & 4 deletions dom/vr/XRView.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ class XRView final : public nsWrapperCache {

explicit XRView(nsISupports* aParent, const XREye& aEye);

void Update(const gfx::PointDouble3D& aPosition,
const gfx::QuaternionDouble& aOrientation,
void Update(const gfx::Matrix4x4Double& aEyeTransform,
const gfx::Matrix4x4& aProjectionMatrix);
// WebIDL Boilerplate
nsISupports* GetParentObject() const { return mParent; }
Expand All @@ -44,8 +43,7 @@ class XRView final : public nsWrapperCache {

nsCOMPtr<nsISupports> mParent;
XREye mEye;
gfx::PointDouble3D mPosition;
gfx::QuaternionDouble mOrientation;
gfx::Matrix4x4Double mEyeTransform;
gfx::Matrix4x4 mProjectionMatrix;
JS::Heap<JSObject*> mJSProjectionMatrix;
bool mProjectionNeedsUpdate = true;
Expand Down
4 changes: 2 additions & 2 deletions gfx/vr/external_api/moz_external_vr.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace gfx {
// running at the same time? Or...what if we have multiple
// release builds running on same machine? (Bug 1563232)
#define SHMEM_VERSION "0.0.11"
static const int32_t kVRExternalVersion = 18;
static const int32_t kVRExternalVersion = 19;

// We assign VR presentations to groups with a bitmask.
// Currently, we will only display either content or chrome.
Expand Down Expand Up @@ -344,7 +344,7 @@ struct VRDisplayState {
VRDisplayCapabilityFlags capabilityFlags;
VRDisplayBlendMode blendMode;
VRFieldOfView eyeFOV[VRDisplayState::NumEyes];
Point3D_POD eyeTranslation[VRDisplayState::NumEyes];
float eyeTransform[VRDisplayState::NumEyes][16];
IntSize_POD eyeResolution;
float nativeFramebufferScaleFactor;
bool suppressFrames;
Expand Down
14 changes: 11 additions & 3 deletions gfx/vr/gfxVR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,17 @@ const IntSize VRDisplayInfo::SuggestedEyeResolution() const {
}

const Point3D VRDisplayInfo::GetEyeTranslation(uint32_t whichEye) const {
return Point3D(mDisplayState.eyeTranslation[whichEye].x,
mDisplayState.eyeTranslation[whichEye].y,
mDisplayState.eyeTranslation[whichEye].z);
return Point3D(mDisplayState.eyeTransform[whichEye][12],
mDisplayState.eyeTransform[whichEye][13],
mDisplayState.eyeTransform[whichEye][14]);
}

const Matrix4x4Double VRDisplayInfo::GetEyeTransform(uint32_t whichEye) const {
Matrix4x4Double m;
for (int i = 0; i < 16; ++i) {
m.components[i] = static_cast<double>(mDisplayState.eyeTransform[whichEye][i]);
}
return m;
}

const Size VRDisplayInfo::GetStageSize() const {
Expand Down
1 change: 1 addition & 0 deletions gfx/vr/gfxVR.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ struct VRDisplayInfo {

const IntSize SuggestedEyeResolution() const;
const Point3D GetEyeTranslation(uint32_t whichEye) const;
const Matrix4x4Double GetEyeTransform(uint32_t whichEye) const;
const VRFieldOfView& GetEyeFOV(uint32_t whichEye) const {
return mDisplayState.eyeFOV[whichEye];
}
Expand Down

0 comments on commit 82051b6

Please sign in to comment.