Bug 1630007 - Apply XRSpace effective origin position and orientation using matrix multiplication. r=kip,daoshengmu

Differential Revision: https://phabricator.services.mozilla.com/D70923

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Imanol Fernandez 2020-04-15 22:05:26 +00:00
parent 01409a49a6
commit c3114c1c70
5 changed files with 39 additions and 26 deletions

View File

@ -60,14 +60,6 @@ already_AddRefed<XRViewerPose> XRFrame::GetViewerPose(
float depthNear = (float)renderState->DepthNear();
float depthFar = (float)renderState->DepthFar();
const gfx::PointDouble3D& originPosition =
aReferenceSpace.GetEffectiveOriginPosition();
const gfx::QuaternionDouble& originOrientation =
aReferenceSpace.GetEffectiveOriginOrientation();
gfx::QuaternionDouble invOriginOrientation = originOrientation;
invOriginOrientation.Invert();
gfx::VRDisplayClient* display = mSession->GetDisplayClient();
if (display) {
// Have a VRDisplayClient
@ -86,14 +78,17 @@ already_AddRefed<XRViewerPose> XRFrame::GetViewerPose(
// TODO: Remove those extra inverts when WebVR support is disabled.
viewerOrientation.Invert();
viewerPosition = invOriginOrientation.RotatePoint(viewerPosition);
viewerPosition -= originPosition;
viewerOrientation *= invOriginOrientation;
gfx::Matrix4x4Double headTransform;
headTransform.SetRotationFromQuaternion(viewerOrientation);
headTransform.PostTranslate(viewerPosition);
gfx::Matrix4x4Double originTransform;
originTransform.SetRotationFromQuaternion(
aReferenceSpace.GetEffectiveOriginOrientation());
originTransform.PreTranslate(-aReferenceSpace.GetEffectiveOriginPosition());
headTransform *= originTransform;
auto addEye = [&](XREye xrEye, VRDisplayState::Eye eye) {
auto offset = displayInfo.GetEyeTranslation(eye);
auto eyeFromHead = gfx::Matrix4x4Double::Translation(
@ -165,21 +160,13 @@ XRPose* XRFrame::GetPose(const XRSpace& aSpace, const XRSpace& aBaseSpace,
// TODO (Bug 1616393) - Check if poses must be limited:
// https://immersive-web.github.io/webxr/#poses-must-be-limited
const gfx::PointDouble3D& originPosition =
aBaseSpace.GetEffectiveOriginPosition();
gfx::PointDouble3D position = aSpace.GetEffectiveOriginPosition();
gfx::QuaternionDouble orientation = aSpace.GetEffectiveOriginOrientation();
gfx::Matrix4x4Double base;
base.SetRotationFromQuaternion(aBaseSpace.GetEffectiveOriginOrientation());
base.PreTranslate(-aBaseSpace.GetEffectiveOriginPosition());
gfx::QuaternionDouble invOriginOrientation(
aBaseSpace.GetEffectiveOriginOrientation());
invOriginOrientation.Invert();
gfx::Matrix4x4Double matrix = aSpace.GetEffectiveOriginTransform() * base;
position = invOriginOrientation.RotatePoint(position);
position -= originPosition;
orientation *= invOriginOrientation;
RefPtr<XRRigidTransform> transform =
new XRRigidTransform(mParent, position, orientation);
RefPtr<XRRigidTransform> transform = new XRRigidTransform(mParent, matrix);
RefPtr<XRPose> pose = new XRPose(mParent, transform, false);
return pose;

View File

@ -42,6 +42,21 @@ XRRigidTransform::XRRigidTransform(nsISupports* aParent,
aOrientation.z, aOrientation.w);
}
XRRigidTransform::XRRigidTransform(nsISupports* aParent,
const gfx::Matrix4x4Double& aTransform)
: mParent(aParent), mMatrixArray(nullptr) {
mozilla::HoldJSObjects(this);
gfx::PointDouble3D position;
gfx::PointDouble3D scale;
gfx::QuaternionDouble orientation;
aTransform.Decompose(position, orientation, scale);
mPosition = new DOMPoint(aParent, position.x, position.y, position.z, 1.0f);
mOrientation = new DOMPoint(aParent, orientation.x, orientation.y,
orientation.z, orientation.w);
}
XRRigidTransform::~XRRigidTransform() { mozilla::DropJSObjects(this); }
/* static */ already_AddRefed<XRRigidTransform> XRRigidTransform::Constructor(

View File

@ -25,6 +25,8 @@ class XRRigidTransform final : public nsWrapperCache {
explicit XRRigidTransform(nsISupports* aParent,
const gfx::PointDouble3D& aPosition,
const gfx::QuaternionDouble& aOrientation);
explicit XRRigidTransform(nsISupports* aParent,
const gfx::Matrix4x4Double& aTransform);
static already_AddRefed<XRRigidTransform> Constructor(
const GlobalObject& aGlobal, const DOMPointInit& aOrigin,
const DOMPointInit& aDirection, ErrorResult& aRv);

View File

@ -40,7 +40,8 @@ JSObject* XRSpace::WrapObject(JSContext* aCx,
XRSession* XRSpace::GetSession() const { return mSession; }
gfx::QuaternionDouble XRSpace::GetEffectiveOriginOrientation() const {
gfx::QuaternionDouble orientation = mNativeOrigin->GetOrientation() * mOriginOffsetOrientation;
gfx::QuaternionDouble orientation =
mNativeOrigin->GetOrientation() * mOriginOffsetOrientation;
return orientation;
}
@ -52,6 +53,13 @@ gfx::PointDouble3D XRSpace::GetEffectiveOriginPosition() const {
return position;
}
gfx::Matrix4x4Double XRSpace::GetEffectiveOriginTransform() const {
gfx::Matrix4x4Double transform;
transform.SetRotationFromQuaternion(GetEffectiveOriginOrientation());
transform.PostTranslate(GetEffectiveOriginPosition());
return transform;
}
bool XRSpace::IsPositionEmulated() const {
gfx::VRDisplayClient* display = mSession->GetDisplayClient();
if (!display) {

View File

@ -37,6 +37,7 @@ class XRSpace : public DOMEventTargetHelper {
// Non webIDL Members
gfx::QuaternionDouble GetEffectiveOriginOrientation() const;
gfx::PointDouble3D GetEffectiveOriginPosition() const;
gfx::Matrix4x4Double GetEffectiveOriginTransform() const;
bool IsPositionEmulated() const;
protected: