tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

XRRigidTransform.cpp (5826B)


      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/. */
      6 
      7 #include "mozilla/dom/XRRigidTransform.h"
      8 
      9 #include "mozilla/HoldDropJSObjects.h"
     10 #include "mozilla/dom/DOMPoint.h"
     11 #include "mozilla/dom/DOMPointBinding.h"
     12 #include "mozilla/dom/Pose.h"
     13 #include "nsWrapperCache.h"
     14 
     15 namespace mozilla::dom {
     16 
     17 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_WITH_JS_MEMBERS(XRRigidTransform,
     18                                                      (mParent, mPosition,
     19                                                       mOrientation, mInverse),
     20                                                      (mMatrixArray))
     21 
     22 XRRigidTransform::XRRigidTransform(nsISupports* aParent,
     23                                   const gfx::PointDouble3D& aPosition,
     24                                   const gfx::QuaternionDouble& aOrientation)
     25    : mParent(aParent),
     26      mMatrixArray(nullptr),
     27      mPosition(nullptr),
     28      mOrientation(nullptr),
     29      mInverse(nullptr),
     30      mRawPosition(aPosition),
     31      mRawOrientation(aOrientation),
     32      mNeedsUpdate(true) {
     33  mozilla::HoldJSObjects(this);
     34  mRawTransformMatrix.SetRotationFromQuaternion(mRawOrientation);
     35  mRawTransformMatrix.PostTranslate(mRawPosition);
     36 }
     37 
     38 XRRigidTransform::XRRigidTransform(nsISupports* aParent,
     39                                   const gfx::Matrix4x4Double& aTransform)
     40    : mParent(aParent),
     41      mMatrixArray(nullptr),
     42      mPosition(nullptr),
     43      mOrientation(nullptr),
     44      mInverse(nullptr),
     45      mNeedsUpdate(true) {
     46  mozilla::HoldJSObjects(this);
     47  gfx::PointDouble3D scale;
     48  mRawTransformMatrix = aTransform;
     49  mRawTransformMatrix.Decompose(mRawPosition, mRawOrientation, scale);
     50 }
     51 
     52 XRRigidTransform::~XRRigidTransform() { mozilla::DropJSObjects(this); }
     53 
     54 /* static */ already_AddRefed<XRRigidTransform> XRRigidTransform::Constructor(
     55    const GlobalObject& aGlobal, const DOMPointInit& aOrigin,
     56    const DOMPointInit& aDirection, ErrorResult& aRv) {
     57  gfx::PointDouble3D position(aOrigin.mX, aOrigin.mY, aOrigin.mZ);
     58  gfx::QuaternionDouble orientation(aDirection.mX, aDirection.mY, aDirection.mZ,
     59                                    aDirection.mW);
     60  orientation.Normalize();
     61  RefPtr<XRRigidTransform> obj =
     62      new XRRigidTransform(aGlobal.GetAsSupports(), position, orientation);
     63  return obj.forget();
     64 }
     65 
     66 JSObject* XRRigidTransform::WrapObject(JSContext* aCx,
     67                                       JS::Handle<JSObject*> aGivenProto) {
     68  return XRRigidTransform_Binding::Wrap(aCx, this, aGivenProto);
     69 }
     70 
     71 DOMPoint* XRRigidTransform::Position() {
     72  if (!mPosition) {
     73    mPosition = new DOMPoint(mParent, mRawPosition.x, mRawPosition.y,
     74                             mRawPosition.z, 1.0f);
     75  }
     76  return mPosition;
     77 }
     78 
     79 DOMPoint* XRRigidTransform::Orientation() {
     80  if (!mOrientation) {
     81    mOrientation = new DOMPoint(mParent, mRawOrientation.x, mRawOrientation.y,
     82                                mRawOrientation.z, mRawOrientation.w);
     83  }
     84  return mOrientation;
     85 }
     86 
     87 XRRigidTransform& XRRigidTransform::operator=(const XRRigidTransform& aOther) {
     88  Update(aOther.mRawPosition, aOther.mRawOrientation);
     89  return *this;
     90 }
     91 
     92 gfx::QuaternionDouble XRRigidTransform::RawOrientation() const {
     93  return mRawOrientation;
     94 }
     95 gfx::PointDouble3D XRRigidTransform::RawPosition() const {
     96  return mRawPosition;
     97 }
     98 
     99 void XRRigidTransform::Update(const gfx::PointDouble3D& aPosition,
    100                              const gfx::QuaternionDouble& aOrientation) {
    101  mNeedsUpdate = true;
    102  mRawPosition = aPosition;
    103  mRawOrientation = aOrientation;
    104  mRawTransformMatrix.SetRotationFromQuaternion(mRawOrientation);
    105  mRawTransformMatrix.PostTranslate(mRawPosition);
    106  UpdateInternal();
    107 }
    108 
    109 void XRRigidTransform::Update(const gfx::Matrix4x4Double& aTransform) {
    110  mNeedsUpdate = true;
    111  mRawTransformMatrix = aTransform;
    112  gfx::PointDouble3D scale;
    113  mRawTransformMatrix.Decompose(mRawPosition, mRawOrientation, scale);
    114  UpdateInternal();
    115 }
    116 
    117 void XRRigidTransform::UpdateInternal() {
    118  if (mPosition) {
    119    mPosition->SetX(mRawPosition.x);
    120    mPosition->SetY(mRawPosition.y);
    121    mPosition->SetZ(mRawPosition.z);
    122  }
    123  if (mOrientation) {
    124    mOrientation->SetX(mRawOrientation.x);
    125    mOrientation->SetY(mRawOrientation.y);
    126    mOrientation->SetZ(mRawOrientation.z);
    127    mOrientation->SetW(mRawOrientation.w);
    128  }
    129  if (mInverse) {
    130    gfx::Matrix4x4Double inverseMatrix = mRawTransformMatrix;
    131    (void)inverseMatrix.Invert();
    132    mInverse->Update(inverseMatrix);
    133  }
    134 }
    135 
    136 void XRRigidTransform::GetMatrix(JSContext* aCx,
    137                                 JS::MutableHandle<JSObject*> aRetval,
    138                                 ErrorResult& aRv) {
    139  if (!mMatrixArray || mNeedsUpdate) {
    140    mNeedsUpdate = false;
    141 
    142    const uint32_t size = 16;
    143    float components[size] = {};
    144    // In order to avoid some platforms which only copy
    145    // the first or last two bytes of a Float64 to a Float32.
    146    for (uint32_t i = 0; i < size; ++i) {
    147      components[i] = mRawTransformMatrix.components[i];
    148    }
    149    Pose::SetFloat32Array(aCx, this, aRetval, mMatrixArray, components, 16,
    150                          aRv);
    151    if (!mMatrixArray) {
    152      return;
    153    }
    154  }
    155  if (mMatrixArray) {
    156    JS::ExposeObjectToActiveJS(mMatrixArray);
    157  }
    158  aRetval.set(mMatrixArray);
    159 }
    160 
    161 already_AddRefed<XRRigidTransform> XRRigidTransform::Inverse() {
    162  if (!mInverse) {
    163    gfx::Matrix4x4Double inverseMatrix = mRawTransformMatrix;
    164    (void)inverseMatrix.Invert();
    165    mInverse = new XRRigidTransform(mParent, inverseMatrix);
    166  }
    167 
    168  RefPtr<XRRigidTransform> inverse = mInverse;
    169  return inverse.forget();
    170 }
    171 
    172 }  // namespace mozilla::dom