Revert "License conversion from Flora to Apache 2.0"
[platform/core/uifw/dali-core.git] / dali / public-api / math / matrix3.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.0 (the License);
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //     http://floralicense.org/license/
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an AS IS BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 // CLASS HEADER
18 #include <dali/public-api/math/matrix3.h>
19
20 // EXTERNAL INCLUDES
21 #include <string.h>
22
23 // INTERNAL INCLUDES
24 #include <dali/public-api/math/math-utils.h>
25
26 #define S00 0
27 #define S01 1
28 #define S02 2
29 #define S10 3
30 #define S11 4
31 #define S12 5
32 #define S20 6
33 #define S21 7
34 #define S22 8
35
36 /*
37  * S00 S01 S02
38  * S10 S11 S12
39  * S20 S21 S22
40  */
41
42 namespace
43 {
44 const size_t NUM_BYTES_IN_ROW    = 3*sizeof(float);
45 const size_t NUM_BYTES_IN_MATRIX = 9*sizeof(float);
46 }
47
48 namespace Dali
49 {
50
51 const Matrix3 Matrix3::IDENTITY(1.0f, 0.0f, 0.0f,
52                                 0.0f, 1.0f, 0.0f,
53                                 0.0f, 0.0f, 1.0f);
54
55 Matrix3::Matrix3()
56 {
57   float* m = AsFloat();
58   memset(m, 0, NUM_BYTES_IN_MATRIX);
59   mElements[S00]=1.0f;
60   mElements[S11]=1.0f;
61   mElements[S22]=1.0f;
62 }
63
64 Matrix3::Matrix3(const Matrix3& m)
65 {
66   memcpy( mElements, m.mElements, NUM_BYTES_IN_MATRIX );
67 }
68
69 Matrix3::Matrix3(const Matrix& matrix)
70 {
71   const float* m4 = matrix.AsFloat();
72   memcpy(&mElements[S00], m4,   NUM_BYTES_IN_ROW);
73   memcpy(&mElements[S10], m4+4, NUM_BYTES_IN_ROW);
74   memcpy(&mElements[S20], m4+8, NUM_BYTES_IN_ROW);
75 }
76
77 Matrix3::Matrix3(float s00, float s01, float s02, float s10, float s11, float s12, float s20, float s21, float s22)
78 {
79   mElements[S00] = s00;
80   mElements[S01] = s01;
81   mElements[S02] = s02;
82   mElements[S10] = s10;
83   mElements[S11] = s11;
84   mElements[S12] = s12;
85   mElements[S20] = s20;
86   mElements[S21] = s21;
87   mElements[S22] = s22;
88 }
89
90
91 void Matrix3::SetIdentity()
92 {
93   memset(mElements, 0, NUM_BYTES_IN_MATRIX);
94   mElements[S00]=1.0f;
95   mElements[S11]=1.0f;
96   mElements[S22]=1.0f;
97 }
98
99 Matrix3& Matrix3::operator=( const Matrix3& matrix )
100 {
101   // no point copying if self assigning
102   if( this != &matrix )
103   {
104     memcpy( AsFloat(), matrix.AsFloat(), NUM_BYTES_IN_MATRIX );
105   }
106   return *this;
107 }
108
109 Matrix3& Matrix3::operator=( const Matrix& matrix )
110 {
111   const float* m4 = matrix.AsFloat();
112   memcpy(&mElements[S00], m4,   NUM_BYTES_IN_ROW);
113   memcpy(&mElements[S10], m4+4, NUM_BYTES_IN_ROW);
114   memcpy(&mElements[S20], m4+8, NUM_BYTES_IN_ROW);
115   return *this;
116 }
117
118 bool Matrix3::Invert()
119 {
120   bool succeeded = false;
121
122   float cof[9];
123   cof[S00] = (mElements[S11] * mElements[S22] - mElements[S12] * mElements[S21]);
124   cof[S01] = (mElements[S02] * mElements[S21] - mElements[S01] * mElements[S22]);
125   cof[S02] = (mElements[S01] * mElements[S12] - mElements[S02] * mElements[S11]);
126
127   cof[S10] = (mElements[S12] * mElements[S20] - mElements[S10] * mElements[S22]);
128   cof[S11] = (mElements[S00] * mElements[S22] - mElements[S02] * mElements[S20]);
129   cof[S12] = (mElements[S02] * mElements[S10] - mElements[S00] * mElements[S12]);
130
131   cof[S20] = (mElements[S10] * mElements[S21] - mElements[S11] * mElements[S20]);
132   cof[S21] = (mElements[S01] * mElements[S20] - mElements[S00] * mElements[S21]);
133   cof[S22] = (mElements[S00] * mElements[S11] - mElements[S01] * mElements[S10]);
134
135   float det = mElements[S00] * cof[S00] + mElements[S01] * cof[S10] + mElements[S02] * cof[S20];
136
137   // In the case where the determinant is exactly zero, the matrix is non-invertible
138   if( ! EqualsZero( det ) )
139   {
140     det = 1.0 / det;
141     for (int i = 0; i < 9; i++)
142     {
143       mElements[i] = cof[i] * det;
144     }
145     succeeded = true;
146   }
147   return succeeded;
148 }
149
150 bool Matrix3::Transpose()
151 {
152   float tmp;
153   tmp = mElements[S01]; mElements[S01] = mElements[S10]; mElements[S10]=tmp;
154   tmp = mElements[S02]; mElements[S02] = mElements[S20]; mElements[S20]=tmp;
155   tmp = mElements[S21]; mElements[S21] = mElements[S12]; mElements[S12]=tmp;
156   return true;
157 }
158
159 bool Matrix3::ScaledInverseTranspose()
160 {
161   bool succeeded = false;
162
163   float cof[9];
164   cof[S00] = (mElements[S11] * mElements[S22] - mElements[S12] * mElements[S21]);
165   cof[S01] = (mElements[S02] * mElements[S21] - mElements[S01] * mElements[S22]);
166   cof[S02] = (mElements[S01] * mElements[S12] - mElements[S02] * mElements[S11]);
167
168   cof[S10] = (mElements[S12] * mElements[S20] - mElements[S10] * mElements[S22]);
169   cof[S11] = (mElements[S00] * mElements[S22] - mElements[S02] * mElements[S20]);
170   cof[S12] = (mElements[S02] * mElements[S10] - mElements[S00] * mElements[S12]);
171
172   cof[S20] = (mElements[S10] * mElements[S21] - mElements[S11] * mElements[S20]);
173   cof[S21] = (mElements[S01] * mElements[S20] - mElements[S00] * mElements[S21]);
174   cof[S22] = (mElements[S00] * mElements[S11] - mElements[S01] * mElements[S10]);
175
176   float det = mElements[S00] * cof[S00] + mElements[S01] * cof[S10] + mElements[S02] * cof[S20];
177
178   // In the case where the determinant is exactly zero, the matrix is non-invertible
179   if( ! EqualsZero( det ) )
180   {
181     // Use average rather than determinant to remove rounding to zero errors in further multiplication
182     float sum=0;
183     for(size_t i=0;i<9;i++)
184     {
185       sum+=fabsf(cof[i]);
186     }
187     float scale = 9.0f/sum; // Inverse of the average values
188     if (det < 0)
189     {
190       // Ensure the signs of the inverse are correct
191       scale = -scale;
192     }
193
194     mElements[S00] = cof[S00] * scale;
195     mElements[S01] = cof[S10] * scale;
196     mElements[S02] = cof[S20] * scale;
197
198     mElements[S10] = cof[S01] * scale;
199     mElements[S11] = cof[S11] * scale;
200     mElements[S12] = cof[S21] * scale;
201
202     mElements[S20] = cof[S02] * scale;
203     mElements[S21] = cof[S12] * scale;
204     mElements[S22] = cof[S22] * scale;
205
206     succeeded = true;
207   }
208   return succeeded;
209 }
210
211 void Matrix3::Scale(float scale)
212 {
213   mElements[S00] *= scale;
214   mElements[S01] *= scale;
215   mElements[S02] *= scale;
216   mElements[S10] *= scale;
217   mElements[S11] *= scale;
218   mElements[S12] *= scale;
219   mElements[S20] *= scale;
220   mElements[S21] *= scale;
221   mElements[S22] *= scale;
222 }
223
224 float Matrix3::Magnitude() const
225 {
226   float avg=0;
227   for(size_t i=0;i<9;i++)
228   {
229     avg+=fabsf(mElements[i]);
230   }
231   return avg/3.0f;
232 }
233
234
235 void Matrix3::Multiply( Matrix3& result, const Matrix3& lhs, const Matrix3& rhs )
236 {
237   float* temp = result.AsFloat();
238   const float* rhsPtr  = rhs.AsFloat();
239   const float* lhsPtr = lhs.AsFloat();
240
241   for( int i=0; i < 3; i++ )
242   {
243     int loc = i * 3;
244     int loc1 = loc + 1;
245     int loc2 = loc + 2;
246
247     float value0 = lhsPtr[loc];
248     float value1 = lhsPtr[loc1];
249     float value2 = lhsPtr[loc2];
250     temp[loc]  = (value0 * rhsPtr[0]) +
251                  (value1 * rhsPtr[3]) +
252                  (value2 * rhsPtr[6]);
253
254     temp[loc1] = (value0 * rhsPtr[1]) +
255                  (value1 * rhsPtr[4]) +
256                  (value2 * rhsPtr[7]);
257
258     temp[loc2] = (value0 * rhsPtr[2]) +
259                  (value1 * rhsPtr[5]) +
260                  (value2 * rhsPtr[8]);
261   }
262 }
263
264 bool Matrix3::operator==(const Matrix3 & rhs) const
265 {
266   return (
267     Equals( mElements[0], rhs.mElements[0]) &&
268     Equals( mElements[1], rhs.mElements[1]) &&
269     Equals( mElements[2], rhs.mElements[2]) &&
270     Equals( mElements[3], rhs.mElements[3]) &&
271     Equals( mElements[4], rhs.mElements[4]) &&
272     Equals( mElements[5], rhs.mElements[5]) &&
273     Equals( mElements[6], rhs.mElements[6]) &&
274     Equals( mElements[7], rhs.mElements[7]) &&
275     Equals( mElements[8], rhs.mElements[8]));
276 }
277
278 bool Matrix3::operator!=(const Matrix3& rhs) const
279 {
280   return !(*this == rhs);
281 }
282
283 std::ostream& operator<< (std::ostream& o, const Matrix3& matrix)
284 {
285   return o << "[ [" << matrix.mElements[0] << ", " << matrix.mElements[1] << ", " << matrix.mElements[2]  << "], "
286              << "[" << matrix.mElements[3] << ", " << matrix.mElements[4] << ", " << matrix.mElements[5]  << "], "
287              << "[" << matrix.mElements[6] << ", " << matrix.mElements[7] << ", " << matrix.mElements[8]  << "] ]";
288 }
289
290 } // namespace Dali