Bug 1880216 - Migrate Fenix docs into Sphinx. r=owlish,geckoview-reviewers,android...
[gecko.git] / dom / vr / XRRigidTransform.cpp
blobd29937c56a36808e98845a9a6673fc92c784a935
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/XRRigidTransform.h"
8 #include "mozilla/dom/DOMPoint.h"
9 #include "mozilla/dom/Pose.h"
10 #include "mozilla/dom/DOMPointBinding.h"
11 #include "mozilla/HoldDropJSObjects.h"
12 #include "nsWrapperCache.h"
14 namespace mozilla::dom {
16 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_WITH_JS_MEMBERS(XRRigidTransform,
17 (mParent, mPosition,
18 mOrientation, mInverse),
19 (mMatrixArray))
21 XRRigidTransform::XRRigidTransform(nsISupports* aParent,
22 const gfx::PointDouble3D& aPosition,
23 const gfx::QuaternionDouble& aOrientation)
24 : mParent(aParent),
25 mMatrixArray(nullptr),
26 mPosition(nullptr),
27 mOrientation(nullptr),
28 mInverse(nullptr),
29 mRawPosition(aPosition),
30 mRawOrientation(aOrientation),
31 mNeedsUpdate(true) {
32 mozilla::HoldJSObjects(this);
33 mRawTransformMatrix.SetRotationFromQuaternion(mRawOrientation);
34 mRawTransformMatrix.PostTranslate(mRawPosition);
37 XRRigidTransform::XRRigidTransform(nsISupports* aParent,
38 const gfx::Matrix4x4Double& aTransform)
39 : mParent(aParent),
40 mMatrixArray(nullptr),
41 mPosition(nullptr),
42 mOrientation(nullptr),
43 mInverse(nullptr),
44 mNeedsUpdate(true) {
45 mozilla::HoldJSObjects(this);
46 gfx::PointDouble3D scale;
47 mRawTransformMatrix = aTransform;
48 mRawTransformMatrix.Decompose(mRawPosition, mRawOrientation, scale);
51 XRRigidTransform::~XRRigidTransform() { mozilla::DropJSObjects(this); }
53 /* static */ already_AddRefed<XRRigidTransform> XRRigidTransform::Constructor(
54 const GlobalObject& aGlobal, const DOMPointInit& aOrigin,
55 const DOMPointInit& aDirection, ErrorResult& aRv) {
56 gfx::PointDouble3D position(aOrigin.mX, aOrigin.mY, aOrigin.mZ);
57 gfx::QuaternionDouble orientation(aDirection.mX, aDirection.mY, aDirection.mZ,
58 aDirection.mW);
59 orientation.Normalize();
60 RefPtr<XRRigidTransform> obj =
61 new XRRigidTransform(aGlobal.GetAsSupports(), position, orientation);
62 return obj.forget();
65 JSObject* XRRigidTransform::WrapObject(JSContext* aCx,
66 JS::Handle<JSObject*> aGivenProto) {
67 return XRRigidTransform_Binding::Wrap(aCx, this, aGivenProto);
70 DOMPoint* XRRigidTransform::Position() {
71 if (!mPosition) {
72 mPosition = new DOMPoint(mParent, mRawPosition.x, mRawPosition.y,
73 mRawPosition.z, 1.0f);
75 return mPosition;
78 DOMPoint* XRRigidTransform::Orientation() {
79 if (!mOrientation) {
80 mOrientation = new DOMPoint(mParent, mRawOrientation.x, mRawOrientation.y,
81 mRawOrientation.z, mRawOrientation.w);
83 return mOrientation;
86 XRRigidTransform& XRRigidTransform::operator=(const XRRigidTransform& aOther) {
87 Update(aOther.mRawPosition, aOther.mRawOrientation);
88 return *this;
91 gfx::QuaternionDouble XRRigidTransform::RawOrientation() const {
92 return mRawOrientation;
94 gfx::PointDouble3D XRRigidTransform::RawPosition() const {
95 return mRawPosition;
98 void XRRigidTransform::Update(const gfx::PointDouble3D& aPosition,
99 const gfx::QuaternionDouble& aOrientation) {
100 mNeedsUpdate = true;
101 mRawPosition = aPosition;
102 mRawOrientation = aOrientation;
103 mRawTransformMatrix.SetRotationFromQuaternion(mRawOrientation);
104 mRawTransformMatrix.PostTranslate(mRawPosition);
105 UpdateInternal();
108 void XRRigidTransform::Update(const gfx::Matrix4x4Double& aTransform) {
109 mNeedsUpdate = true;
110 mRawTransformMatrix = aTransform;
111 gfx::PointDouble3D scale;
112 mRawTransformMatrix.Decompose(mRawPosition, mRawOrientation, scale);
113 UpdateInternal();
116 void XRRigidTransform::UpdateInternal() {
117 if (mPosition) {
118 mPosition->SetX(mRawPosition.x);
119 mPosition->SetY(mRawPosition.y);
120 mPosition->SetZ(mRawPosition.z);
122 if (mOrientation) {
123 mOrientation->SetX(mRawOrientation.x);
124 mOrientation->SetY(mRawOrientation.y);
125 mOrientation->SetZ(mRawOrientation.z);
126 mOrientation->SetW(mRawOrientation.w);
128 if (mInverse) {
129 gfx::Matrix4x4Double inverseMatrix = mRawTransformMatrix;
130 Unused << inverseMatrix.Invert();
131 mInverse->Update(inverseMatrix);
135 void XRRigidTransform::GetMatrix(JSContext* aCx,
136 JS::MutableHandle<JSObject*> aRetval,
137 ErrorResult& aRv) {
138 if (!mMatrixArray || mNeedsUpdate) {
139 mNeedsUpdate = false;
141 const uint32_t size = 16;
142 float components[size] = {};
143 // In order to avoid some platforms which only copy
144 // the first or last two bytes of a Float64 to a Float32.
145 for (uint32_t i = 0; i < size; ++i) {
146 components[i] = mRawTransformMatrix.components[i];
148 Pose::SetFloat32Array(aCx, this, aRetval, mMatrixArray, components, 16,
149 aRv);
150 if (!mMatrixArray) {
151 return;
154 if (mMatrixArray) {
155 JS::ExposeObjectToActiveJS(mMatrixArray);
157 aRetval.set(mMatrixArray);
160 already_AddRefed<XRRigidTransform> XRRigidTransform::Inverse() {
161 if (!mInverse) {
162 gfx::Matrix4x4Double inverseMatrix = mRawTransformMatrix;
163 Unused << inverseMatrix.Invert();
164 mInverse = new XRRigidTransform(mParent, inverseMatrix);
167 RefPtr<XRRigidTransform> inverse = mInverse;
168 return inverse.forget();
171 } // namespace mozilla::dom