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
,
18 mOrientation
, mInverse
),
21 XRRigidTransform::XRRigidTransform(nsISupports
* aParent
,
22 const gfx::PointDouble3D
& aPosition
,
23 const gfx::QuaternionDouble
& aOrientation
)
25 mMatrixArray(nullptr),
27 mOrientation(nullptr),
29 mRawPosition(aPosition
),
30 mRawOrientation(aOrientation
),
32 mozilla::HoldJSObjects(this);
33 mRawTransformMatrix
.SetRotationFromQuaternion(mRawOrientation
);
34 mRawTransformMatrix
.PostTranslate(mRawPosition
);
37 XRRigidTransform::XRRigidTransform(nsISupports
* aParent
,
38 const gfx::Matrix4x4Double
& aTransform
)
40 mMatrixArray(nullptr),
42 mOrientation(nullptr),
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
,
59 orientation
.Normalize();
60 RefPtr
<XRRigidTransform
> obj
=
61 new XRRigidTransform(aGlobal
.GetAsSupports(), position
, orientation
);
65 JSObject
* XRRigidTransform::WrapObject(JSContext
* aCx
,
66 JS::Handle
<JSObject
*> aGivenProto
) {
67 return XRRigidTransform_Binding::Wrap(aCx
, this, aGivenProto
);
70 DOMPoint
* XRRigidTransform::Position() {
72 mPosition
= new DOMPoint(mParent
, mRawPosition
.x
, mRawPosition
.y
,
73 mRawPosition
.z
, 1.0f
);
78 DOMPoint
* XRRigidTransform::Orientation() {
80 mOrientation
= new DOMPoint(mParent
, mRawOrientation
.x
, mRawOrientation
.y
,
81 mRawOrientation
.z
, mRawOrientation
.w
);
86 XRRigidTransform
& XRRigidTransform::operator=(const XRRigidTransform
& aOther
) {
87 Update(aOther
.mRawPosition
, aOther
.mRawOrientation
);
91 gfx::QuaternionDouble
XRRigidTransform::RawOrientation() const {
92 return mRawOrientation
;
94 gfx::PointDouble3D
XRRigidTransform::RawPosition() const {
98 void XRRigidTransform::Update(const gfx::PointDouble3D
& aPosition
,
99 const gfx::QuaternionDouble
& aOrientation
) {
101 mRawPosition
= aPosition
;
102 mRawOrientation
= aOrientation
;
103 mRawTransformMatrix
.SetRotationFromQuaternion(mRawOrientation
);
104 mRawTransformMatrix
.PostTranslate(mRawPosition
);
108 void XRRigidTransform::Update(const gfx::Matrix4x4Double
& aTransform
) {
110 mRawTransformMatrix
= aTransform
;
111 gfx::PointDouble3D scale
;
112 mRawTransformMatrix
.Decompose(mRawPosition
, mRawOrientation
, scale
);
116 void XRRigidTransform::UpdateInternal() {
118 mPosition
->SetX(mRawPosition
.x
);
119 mPosition
->SetY(mRawPosition
.y
);
120 mPosition
->SetZ(mRawPosition
.z
);
123 mOrientation
->SetX(mRawOrientation
.x
);
124 mOrientation
->SetY(mRawOrientation
.y
);
125 mOrientation
->SetZ(mRawOrientation
.z
);
126 mOrientation
->SetW(mRawOrientation
.w
);
129 gfx::Matrix4x4Double inverseMatrix
= mRawTransformMatrix
;
130 Unused
<< inverseMatrix
.Invert();
131 mInverse
->Update(inverseMatrix
);
135 void XRRigidTransform::GetMatrix(JSContext
* aCx
,
136 JS::MutableHandle
<JSObject
*> aRetval
,
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,
155 JS::ExposeObjectToActiveJS(mMatrixArray
);
157 aRetval
.set(mMatrixArray
);
160 already_AddRefed
<XRRigidTransform
> XRRigidTransform::Inverse() {
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