33#include < reanimated/CSS/common/definitions.h>
44
55#include < folly/dynamic.h>
6+ #include < memory>
67#include < string>
78#include < utility>
89
910namespace reanimated ::css {
1011
1112class TransformMatrix {
1213 public:
13- virtual ~TransformMatrix () = default ;
14-
15- virtual double determinant () const = 0;
14+ using Shared = std::shared_ptr<const TransformMatrix>;
1615
17- virtual double & operator []( size_t index ) = 0 ;
18- virtual const double & operator []( size_t index) const = 0 ;
16+ TransformMatrix ( ) = default ;
17+ virtual ~TransformMatrix () = default ;
1918
2019 virtual size_t getDimension () const = 0;
20+ virtual size_t getSize () const = 0;
21+
22+ virtual bool isSingular () const = 0;
23+ virtual bool normalize () = 0;
24+ virtual void transpose () = 0;
25+ virtual double determinant () const = 0;
2126
2227 virtual std::string toString () const = 0;
2328 virtual folly::dynamic toDynamic () const = 0;
29+
30+ virtual double &operator [](size_t index) = 0 ;
31+ virtual const double &operator [](size_t index) const = 0 ;
32+ virtual bool operator ==(const TransformMatrix &other) const = 0 ;
2433};
2534
2635template <typename TDerived, size_t TDimension>
@@ -29,51 +38,72 @@ class TransformMatrixBase : public TransformMatrix {
2938 static constexpr size_t SIZE = TDimension * TDimension;
3039 using MatrixArray = std::array<double , SIZE>;
3140
32- explicit TransformMatrixBase (MatrixArray matrix)
33- : matrix_(std::move(matrix)) {}
34-
35- explicit TransformMatrixBase (jsi::Runtime &rt, const jsi::Value &value) {
36- const auto array = value.asObject (rt).asArray (rt);
37- if (array.size (rt) != SIZE) {
38- throw std::invalid_argument (
39- " [Reanimated] Matrix array should have " + std::to_string (SIZE) +
40- " elements" );
41- }
42-
43- for (size_t i = 0 ; i < SIZE; ++i) {
44- matrix_[i] = array.getValueAtIndex (rt, i).asNumber ();
41+ TransformMatrixBase () : TransformMatrix(), matrix_{} {
42+ // Create an identity matrix
43+ for (size_t i = 0 ; i < TDimension; ++i) {
44+ matrix_[i * (TDimension + 1 )] = 1 ;
4545 }
4646 }
4747
48- explicit TransformMatrixBase (const folly::dynamic &array) {
49- if (!array.isArray () || array.size () != SIZE) {
50- throw std::invalid_argument (
51- " [Reanimated] Matrix array should have " + std::to_string (SIZE) +
52- " elements" );
53- }
48+ explicit TransformMatrixBase (MatrixArray matrix)
49+ : TransformMatrix(), matrix_(std::move(matrix)) {}
5450
55- for (size_t i = 0 ; i < SIZE; ++i) {
56- matrix_[i] = array[i].asDouble ();
57- }
51+ TransformMatrixBase (const TransformMatrixBase &other)
52+ : TransformMatrix(), matrix_(other.matrix_) {}
53+
54+ TransformMatrixBase (TransformMatrixBase &&other) noexcept
55+ : TransformMatrix(), matrix_(std::move(other.matrix_)) {}
56+
57+ inline bool operator ==(const TDerived &other) const {
58+ return matrix_ == other.matrix_ ;
5859 }
5960
60- virtual bool operator ==(const TDerived &other) const = 0 ;
61+ inline bool operator ==(const TransformMatrix &other) const override {
62+ return TDimension == other.getDimension () &&
63+ matrix_ == static_cast <const TDerived &>(other).matrix_ ;
64+ }
6165
62- double &operator [](size_t index) override {
66+ inline double &operator [](size_t index) override {
6367 return matrix_[index];
6468 }
6569
66- const double &operator [](size_t index) const override {
70+ inline const double &operator [](size_t index) const override {
6771 return matrix_[index];
6872 }
6973
70- TDerived operator *( const TDerived &rhs ) const {
71- return TDerived ( multiply (rhs)) ;
74+ size_t getDimension ( ) const override {
75+ return TDimension ;
7276 }
7377
74- TDerived &operator *=(const TDerived &rhs) {
75- matrix_ = multiply (rhs);
76- return static_cast <TDerived &>(*this );
78+ size_t getSize () const override {
79+ return SIZE;
80+ }
81+
82+ bool isSingular () const override {
83+ return determinant () == 0 ;
84+ }
85+
86+ bool normalize () override {
87+ const auto last = matrix_[SIZE - 1 ];
88+ if (last == 0 ) {
89+ return false ;
90+ }
91+ if (last == 1 ) {
92+ return true ;
93+ }
94+
95+ for (size_t i = 0 ; i < SIZE; ++i) {
96+ matrix_[i] /= last;
97+ }
98+ return true ;
99+ }
100+
101+ void transpose () override {
102+ for (size_t i = 0 ; i < TDimension; ++i) {
103+ for (size_t j = i + 1 ; j < TDimension; ++j) {
104+ std::swap (matrix_[i * TDimension + j], matrix_[j * TDimension + i]);
105+ }
106+ }
77107 }
78108
79109 std::string toString () const override {
@@ -96,50 +126,46 @@ class TransformMatrixBase : public TransformMatrix {
96126 return result;
97127 }
98128
99- size_t getDimension ( ) const override {
100- return TDimension ;
129+ inline TDerived operator *( const TDerived &rhs ) const {
130+ return TDerived ( multiply (rhs)) ;
101131 }
102132
103- bool isSingular () const {
104- return determinant () == 0 ;
133+ inline TDerived &operator *=(const TDerived &rhs) {
134+ matrix_ = multiply (rhs);
135+ return static_cast <TDerived &>(*this );
105136 }
106137
107- bool normalize () {
108- const auto last = matrix_[SIZE - 1 ];
109- if (last == 0 ) {
110- return false ;
111- }
112- if (last == 1 ) {
113- return true ;
114- }
115-
116- for (size_t i = 0 ; i < SIZE; ++i) {
117- matrix_[i] /= last;
138+ TransformMatrixBase &operator =(const TransformMatrixBase &other) {
139+ if (this != &other) {
140+ // Note: dimension_ is const, so we can't reassign it
141+ // But since all instances have the same dimension, this is fine
142+ matrix_ = other.matrix_ ;
118143 }
119- return true ;
144+ return * this ;
120145 }
121146
122- void transpose () {
123- for (size_t i = 0 ; i < TDimension; ++i) {
124- for (size_t j = i + 1 ; j < TDimension; ++j) {
125- std::swap (matrix_[i * TDimension + j], matrix_[j * TDimension + i]);
126- }
147+ TransformMatrixBase &operator =(TransformMatrixBase &&other) noexcept {
148+ if (this != &other) {
149+ matrix_ = std::move (other.matrix_ );
127150 }
151+ return *this ;
128152 }
129153
130154 protected:
131155 std::array<double , SIZE> matrix_;
132156
133157 MatrixArray multiply (const TDerived &rhs) const {
134- std::array<double , SIZE> result{};
158+ MatrixArray result{};
159+
135160 for (size_t i = 0 ; i < TDimension; ++i) {
136- for (size_t j = 0 ; j < TDimension; ++j ) {
137- for ( size_t k = 0 ; k < TDimension; ++k) {
138- result[i * TDimension + j] +=
139- matrix_ [i * TDimension + k] * rhs[k * TDimension + j];
161+ for (size_t k = 0 ; k < TDimension; ++k ) {
162+ double temp = matrix_[i * TDimension + k];
163+ for ( size_t j = 0 ; j < TDimension; ++j) {
164+ result [i * TDimension + j] += temp * rhs[k * TDimension + j];
140165 }
141166 }
142167 }
168+
143169 return result;
144170 }
145171};
0 commit comments