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"
16 NS_IMPL_CYCLE_COLLECTION_CLASS(XRRigidTransform
)
18 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(XRRigidTransform
)
19 NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent
, mPosition
, mOrientation
, mInverse
)
20 NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
21 tmp
->mMatrixArray
= nullptr;
22 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
24 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(XRRigidTransform
)
25 NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mParent
, mPosition
, mOrientation
, mInverse
)
26 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
28 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(XRRigidTransform
)
29 NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
30 NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mMatrixArray
)
31 NS_IMPL_CYCLE_COLLECTION_TRACE_END
33 NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(XRRigidTransform
, AddRef
)
34 NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(XRRigidTransform
, Release
)
36 XRRigidTransform::XRRigidTransform(nsISupports
* aParent
,
37 const gfx::PointDouble3D
& aPosition
,
38 const gfx::QuaternionDouble
& aOrientation
)
40 mMatrixArray(nullptr),
42 mOrientation(nullptr),
44 mRawPosition(aPosition
),
45 mRawOrientation(aOrientation
),
47 mozilla::HoldJSObjects(this);
48 mRawTransformMatrix
.SetRotationFromQuaternion(mRawOrientation
);
49 mRawTransformMatrix
.PostTranslate(mRawPosition
);
52 XRRigidTransform::XRRigidTransform(nsISupports
* aParent
,
53 const gfx::Matrix4x4Double
& aTransform
)
55 mMatrixArray(nullptr),
57 mOrientation(nullptr),
60 mozilla::HoldJSObjects(this);
61 gfx::PointDouble3D scale
;
62 mRawTransformMatrix
= aTransform
;
63 mRawTransformMatrix
.Decompose(mRawPosition
, mRawOrientation
, scale
);
66 XRRigidTransform::~XRRigidTransform() { mozilla::DropJSObjects(this); }
68 /* static */ already_AddRefed
<XRRigidTransform
> XRRigidTransform::Constructor(
69 const GlobalObject
& aGlobal
, const DOMPointInit
& aOrigin
,
70 const DOMPointInit
& aDirection
, ErrorResult
& aRv
) {
71 gfx::PointDouble3D
position(aOrigin
.mX
, aOrigin
.mY
, aOrigin
.mZ
);
72 gfx::QuaternionDouble
orientation(aDirection
.mX
, aDirection
.mY
, aDirection
.mZ
,
74 orientation
.Normalize();
75 RefPtr
<XRRigidTransform
> obj
=
76 new XRRigidTransform(aGlobal
.GetAsSupports(), position
, orientation
);
80 JSObject
* XRRigidTransform::WrapObject(JSContext
* aCx
,
81 JS::Handle
<JSObject
*> aGivenProto
) {
82 return XRRigidTransform_Binding::Wrap(aCx
, this, aGivenProto
);
85 DOMPoint
* XRRigidTransform::Position() {
87 mPosition
= new DOMPoint(mParent
, mRawPosition
.x
, mRawPosition
.y
,
88 mRawPosition
.z
, 1.0f
);
93 DOMPoint
* XRRigidTransform::Orientation() {
95 mOrientation
= new DOMPoint(mParent
, mRawOrientation
.x
, mRawOrientation
.y
,
96 mRawOrientation
.z
, mRawOrientation
.w
);
101 XRRigidTransform
& XRRigidTransform::operator=(const XRRigidTransform
& aOther
) {
102 Update(aOther
.mRawPosition
, aOther
.mRawOrientation
);
106 gfx::QuaternionDouble
XRRigidTransform::RawOrientation() const {
107 return mRawOrientation
;
109 gfx::PointDouble3D
XRRigidTransform::RawPosition() const {
113 void XRRigidTransform::Update(const gfx::PointDouble3D
& aPosition
,
114 const gfx::QuaternionDouble
& aOrientation
) {
116 mRawPosition
= aPosition
;
117 mRawOrientation
= aOrientation
;
118 mRawTransformMatrix
.SetRotationFromQuaternion(mRawOrientation
);
119 mRawTransformMatrix
.PostTranslate(mRawPosition
);
123 void XRRigidTransform::Update(const gfx::Matrix4x4Double
& aTransform
) {
125 mRawTransformMatrix
= aTransform
;
126 gfx::PointDouble3D scale
;
127 mRawTransformMatrix
.Decompose(mRawPosition
, mRawOrientation
, scale
);
131 void XRRigidTransform::UpdateInternal() {
133 mPosition
->SetX(mRawPosition
.x
);
134 mPosition
->SetY(mRawPosition
.y
);
135 mPosition
->SetZ(mRawPosition
.z
);
138 mOrientation
->SetX(mRawOrientation
.x
);
139 mOrientation
->SetY(mRawOrientation
.y
);
140 mOrientation
->SetZ(mRawOrientation
.z
);
141 mOrientation
->SetW(mRawOrientation
.w
);
144 gfx::Matrix4x4Double inverseMatrix
= mRawTransformMatrix
;
145 Unused
<< inverseMatrix
.Invert();
146 mInverse
->Update(inverseMatrix
);
150 void XRRigidTransform::GetMatrix(JSContext
* aCx
,
151 JS::MutableHandle
<JSObject
*> aRetval
,
153 if (!mMatrixArray
|| mNeedsUpdate
) {
154 mNeedsUpdate
= false;
156 const uint32_t size
= 16;
157 float components
[size
] = {};
158 // In order to avoid some platforms which only copy
159 // the first or last two bytes of a Float64 to a Float32.
160 for (uint32_t i
= 0; i
< size
; ++i
) {
161 components
[i
] = mRawTransformMatrix
.components
[i
];
163 Pose::SetFloat32Array(aCx
, this, aRetval
, mMatrixArray
, components
, 16,
170 JS::ExposeObjectToActiveJS(mMatrixArray
);
172 aRetval
.set(mMatrixArray
);
175 already_AddRefed
<XRRigidTransform
> XRRigidTransform::Inverse() {
177 gfx::Matrix4x4Double inverseMatrix
= mRawTransformMatrix
;
178 Unused
<< inverseMatrix
.Invert();
179 mInverse
= new XRRigidTransform(mParent
, inverseMatrix
);
182 RefPtr
<XRRigidTransform
> inverse
= mInverse
;
183 return inverse
.forget();
187 } // namespace mozilla