sync with tizen_2.0
[platform/framework/native/appfw.git] / src / base / FBaseFloatMatrix3.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file        FBaseFloatMatrix3.cpp
20  * @brief       This is the implementation for FloatMatrix class.
21  */
22
23 #include <FBaseFloatMatrix3.h>
24 #include <FBaseSysLog.h>
25
26 namespace Tizen { namespace Base
27 {
28
29 static const int MATRIX_SIZE = sizeof(float) * 9;
30 #define SWAP_VALUES(a, b, tmp) \
31         tmp = a; \
32         a = b; \
33         b = tmp;
34
35 FloatMatrix3::FloatMatrix3(void)
36         : __pImpl(null)
37 {
38         SetAsNull();
39 }
40
41 FloatMatrix3::FloatMatrix3(const FloatMatrix3& rhs)
42         : __pImpl(null)
43 {
44         memcpy(matrix, rhs.matrix, MATRIX_SIZE);
45 }
46
47 FloatMatrix3::FloatMatrix3(const float matrix[3][3])
48         : __pImpl(null)
49 {
50         memcpy(this->matrix, matrix, MATRIX_SIZE);
51 }
52
53 FloatMatrix3::~FloatMatrix3(void)
54 {
55 }
56
57 bool
58 FloatMatrix3::operator ==(const FloatMatrix3& rhs) const
59 {
60         if (this == &rhs)
61         {
62                 return true;
63         }
64
65         return (matrix[0][0] == rhs.matrix[0][0] &&
66                         matrix[0][1] == rhs.matrix[0][1] &&
67                         matrix[0][2] == rhs.matrix[0][2] &&
68                         matrix[1][0] == rhs.matrix[1][0] &&
69                         matrix[1][1] == rhs.matrix[1][1] &&
70                         matrix[1][2] == rhs.matrix[1][2] &&
71                         matrix[2][0] == rhs.matrix[2][0] &&
72                         matrix[2][1] == rhs.matrix[2][1] &&
73                         matrix[2][2] == rhs.matrix[2][2]);
74 }
75
76 bool
77 FloatMatrix3::operator !=(const FloatMatrix3& rhs) const
78 {
79         return !(*this == rhs);
80 }
81
82 FloatMatrix3&
83 FloatMatrix3::operator =(const FloatMatrix3& rhs)
84 {
85         if (this != &rhs)
86         {
87                 memcpy(matrix, rhs.matrix, MATRIX_SIZE);
88         }
89
90         return *this;
91 }
92
93 FloatMatrix3&
94 FloatMatrix3::operator =(float value)
95 {
96         matrix[0][0] = value;
97         matrix[1][0] = value;
98         matrix[2][0] = value;
99
100         matrix[0][1] = value;
101         matrix[1][1] = value;
102         matrix[2][1] = value;
103
104         matrix[0][2] = value;
105         matrix[1][2] = value;
106         matrix[2][2] = value;
107
108         return *this;
109 }
110
111 FloatMatrix3
112 FloatMatrix3::operator *(const FloatMatrix3& rhs) const  // need to check performance
113 {
114         FloatMatrix3 resultMatrix;
115
116         resultMatrix.matrix[0][0] = matrix[0][0] * rhs.matrix[0][0] + matrix[0][1] * rhs.matrix[1][0] + matrix[0][2] * rhs.matrix[2][0];
117         resultMatrix.matrix[0][1] = matrix[0][0] * rhs.matrix[0][1] + matrix[0][1] * rhs.matrix[1][1] + matrix[0][2] * rhs.matrix[2][1];
118         resultMatrix.matrix[0][2] = matrix[0][0] * rhs.matrix[0][2] + matrix[0][1] * rhs.matrix[1][2] + matrix[0][2] * rhs.matrix[2][2];
119
120         resultMatrix.matrix[1][0] = matrix[1][0] * rhs.matrix[0][0] + matrix[1][1] * rhs.matrix[1][0] + matrix[1][2] * rhs.matrix[2][0];
121         resultMatrix.matrix[1][1] = matrix[1][0] * rhs.matrix[0][1] + matrix[1][1] * rhs.matrix[1][1] + matrix[1][2] * rhs.matrix[2][1];
122         resultMatrix.matrix[1][2] = matrix[1][0] * rhs.matrix[0][2] + matrix[1][1] * rhs.matrix[1][2] + matrix[1][2] * rhs.matrix[2][2];
123
124         resultMatrix.matrix[2][0] = matrix[2][0] * rhs.matrix[0][0] + matrix[2][1] * rhs.matrix[1][0] + matrix[2][2] * rhs.matrix[2][0];
125         resultMatrix.matrix[2][1] = matrix[2][0] * rhs.matrix[0][1] + matrix[2][1] * rhs.matrix[1][1] + matrix[2][2] * rhs.matrix[2][1];
126         resultMatrix.matrix[2][2] = matrix[2][0] * rhs.matrix[0][2] + matrix[2][1] * rhs.matrix[1][2] + matrix[2][2] * rhs.matrix[2][2];
127
128         return resultMatrix;
129 }
130
131 FloatMatrix3
132 FloatMatrix3::operator *(float value) const
133 {
134         FloatMatrix3 resultMatrix(matrix);
135
136         resultMatrix.matrix[0][0] *= value;
137         resultMatrix.matrix[0][1] *= value;
138         resultMatrix.matrix[0][2] *= value;
139
140         resultMatrix.matrix[1][0] *= value;
141         resultMatrix.matrix[1][1] *= value;
142         resultMatrix.matrix[1][2] *= value;
143
144         resultMatrix.matrix[2][0] *= value;
145         resultMatrix.matrix[2][1] *= value;
146         resultMatrix.matrix[2][2] *= value;
147
148         return resultMatrix;
149 }
150
151 FloatMatrix3
152 FloatMatrix3::operator +(const FloatMatrix3& rhs) const
153 {
154         FloatMatrix3 resultMatrix(matrix);
155
156         resultMatrix.matrix[0][0] += rhs.matrix[0][0];
157         resultMatrix.matrix[0][1] += rhs.matrix[0][1];
158         resultMatrix.matrix[0][2] += rhs.matrix[0][2];
159
160         resultMatrix.matrix[1][0] += rhs.matrix[1][0];
161         resultMatrix.matrix[1][1] += rhs.matrix[1][1];
162         resultMatrix.matrix[1][2] += rhs.matrix[1][2];
163
164         resultMatrix.matrix[2][0] += rhs.matrix[2][0];
165         resultMatrix.matrix[2][1] += rhs.matrix[2][1];
166         resultMatrix.matrix[2][2] += rhs.matrix[2][2];
167
168         return resultMatrix;
169 }
170
171 FloatMatrix3
172 FloatMatrix3::operator +(float value) const
173 {
174         FloatMatrix3 resultMatrix(matrix);
175
176         resultMatrix.matrix[0][0] += value;
177         resultMatrix.matrix[0][1] += value;
178         resultMatrix.matrix[0][2] += value;
179
180         resultMatrix.matrix[1][0] += value;
181         resultMatrix.matrix[1][1] += value;
182         resultMatrix.matrix[1][2] += value;
183
184         resultMatrix.matrix[2][0] += value;
185         resultMatrix.matrix[2][1] += value;
186         resultMatrix.matrix[2][2] += value;
187
188         return resultMatrix;
189 }
190
191 FloatMatrix3
192 FloatMatrix3::operator -(const FloatMatrix3& rhs) const
193 {
194         FloatMatrix3 resultMatrix(matrix);
195
196         resultMatrix.matrix[0][0] -= rhs.matrix[0][0];
197         resultMatrix.matrix[0][1] -= rhs.matrix[0][1];
198         resultMatrix.matrix[0][2] -= rhs.matrix[0][2];
199
200         resultMatrix.matrix[1][0] -= rhs.matrix[1][0];
201         resultMatrix.matrix[1][1] -= rhs.matrix[1][1];
202         resultMatrix.matrix[1][2] -= rhs.matrix[1][2];
203
204         resultMatrix.matrix[2][0] -= rhs.matrix[2][0];
205         resultMatrix.matrix[2][1] -= rhs.matrix[2][1];
206         resultMatrix.matrix[2][2] -= rhs.matrix[2][2];
207
208         return resultMatrix;
209 }
210
211 FloatMatrix3
212 FloatMatrix3::operator -(float value) const
213 {
214         FloatMatrix3 resultMatrix(matrix);
215
216         resultMatrix.matrix[0][0] -= value;
217         resultMatrix.matrix[0][1] -= value;
218         resultMatrix.matrix[0][2] -= value;
219
220         resultMatrix.matrix[1][0] -= value;
221         resultMatrix.matrix[1][1] -= value;
222         resultMatrix.matrix[1][2] -= value;
223
224         resultMatrix.matrix[2][0] -= value;
225         resultMatrix.matrix[2][1] -= value;
226         resultMatrix.matrix[2][2] -= value;
227
228         return resultMatrix;
229 }
230
231 FloatMatrix3&
232 FloatMatrix3::operator *=(const FloatMatrix3& rhs)
233 {
234         *this = *this * rhs;
235         return *this;
236 }
237
238 FloatMatrix3&
239 FloatMatrix3::operator *=(float value)
240 {
241         *this = *this * value;
242         return *this;
243 }
244
245 FloatMatrix3&
246 FloatMatrix3::operator +=(const FloatMatrix3& rhs)
247 {
248         *this = *this + rhs;
249         return *this;
250 }
251
252 FloatMatrix3&
253 FloatMatrix3::operator +=(float value)
254 {
255         *this = *this + value;
256         return *this;
257 }
258
259 FloatMatrix3&
260 FloatMatrix3::operator -=(const FloatMatrix3& rhs)
261 {
262         *this = *this - rhs;
263         return *this;
264 }
265
266 FloatMatrix3&
267 FloatMatrix3::operator -=(float value)
268 {
269         *this = *this - value;
270         return *this;
271 }
272
273 FloatMatrix3
274 operator +(const float& value, const FloatMatrix3& rhs)
275 {
276         return rhs + value;
277 }
278
279 FloatMatrix3
280 operator *(const float& value, const FloatMatrix3& rhs)
281 {
282         return rhs * value;
283 }
284
285 FloatMatrix3
286 operator -(const float& value, const FloatMatrix3& rhs)
287 {
288         FloatMatrix3 returnMatrix(rhs);
289         returnMatrix.Negate();
290         returnMatrix += value;
291         return returnMatrix;
292 }
293
294 bool
295 FloatMatrix3::Equals(const Tizen::Base::Object& obj) const
296 {
297         const FloatMatrix3* pMatrix = dynamic_cast <const FloatMatrix3*>(&obj);
298
299         if (pMatrix == null)
300         {
301                 return false;
302         }
303
304         return (*this == *pMatrix);
305 }
306
307 int
308 FloatMatrix3::GetHashCode(void) const
309 {
310         return (Tizen::Base::Float::GetHashCode(this->matrix[0][0]) + Tizen::Base::Float::GetHashCode(this->matrix[1][0]) +
311                         Tizen::Base::Float::GetHashCode(this->matrix[2][0]) + Tizen::Base::Float::GetHashCode(this->matrix[0][1]) +
312                         Tizen::Base::Float::GetHashCode(this->matrix[1][1]) + Tizen::Base::Float::GetHashCode(this->matrix[2][1]) +
313                         Tizen::Base::Float::GetHashCode(this->matrix[0][2]) + Tizen::Base::Float::GetHashCode(this->matrix[1][2]) +
314                         Tizen::Base::Float::GetHashCode(this->matrix[2][2]));
315 }
316
317 float
318 FloatMatrix3::GetDeterminant(void) const
319 {
320         float a0 = matrix[1][1] * matrix[2][2] - matrix[2][1] * matrix[1][2];
321         float a1 = matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0];
322         float a2 = matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0];
323
324         return matrix[0][0] * a0 - matrix[0][1] * a1 + matrix[0][2] * a2;
325 }
326
327 FloatMatrix3
328 FloatMatrix3::GetInverse(void) const
329 {
330         float a0 = matrix[1][1] * matrix[2][2] - matrix[2][1] * matrix[1][2];
331         float a1 = matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0];
332         float a2 = matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0];
333
334         float determinant = matrix[0][0] * a0 - matrix[0][1] * a1 + matrix[0][2] * a2;
335
336         if (Tizen::Base::Float::Compare(determinant, 0.0f) == 0)
337         {
338                 return *this;
339         }
340
341         float inverseMatrix[3][3];
342
343         inverseMatrix[0][0] = (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1]) / determinant;
344         inverseMatrix[1][0] = (-matrix[1][0] * matrix[2][2] + matrix[1][2] * matrix[2][0]) / determinant;
345         inverseMatrix[2][0] = (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]) / determinant;
346
347         inverseMatrix[0][1] = (-matrix[0][1] * matrix[2][2] + matrix[0][2] * matrix[2][1]) / determinant;
348         inverseMatrix[1][1] = (matrix[0][0] * matrix[2][2] - matrix[0][2] * matrix[2][0]) / determinant;
349         inverseMatrix[2][1] = (-matrix[0][0] * matrix[2][1] + matrix[0][1] * matrix[2][0]) / determinant;
350
351         inverseMatrix[0][2] = (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]) / determinant;
352         inverseMatrix[1][2] = (-matrix[0][0] * matrix[1][2] + matrix[0][2] * matrix[1][0]) / determinant;
353         inverseMatrix[2][2] = (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]) / determinant;
354
355         return FloatMatrix3(inverseMatrix);
356 }
357
358 float
359 FloatMatrix3::GetTrace(void) const
360 {
361         return matrix[0][0] + matrix[1][1] + matrix[2][2];
362 }
363
364 FloatMatrix3
365 FloatMatrix3::GetTranspose(void) const
366 {
367         FloatMatrix3 transposeMatrix(matrix);
368         transposeMatrix.Transpose();
369
370         return transposeMatrix;
371 }
372
373 bool
374 FloatMatrix3::IsIdentity(void) const
375 {
376         if ((Tizen::Base::Float::Compare(matrix[0][0], 1.0f) != 0) || (Tizen::Base::Float::Compare(matrix[1][1], 1.0f) != 0) ||
377                 (Tizen::Base::Float::Compare(matrix[2][2], 1.0f) != 0))
378         {
379                 return false;
380         }
381
382         if ((Tizen::Base::Float::Compare(matrix[0][1], 0.0f) != 0) || (Tizen::Base::Float::Compare(matrix[0][2], 0.0f) != 0) ||
383                 (Tizen::Base::Float::Compare(matrix[1][0], 0.0f) != 0) || (Tizen::Base::Float::Compare(matrix[1][2], 0.0f) != 0) ||
384                 (Tizen::Base::Float::Compare(matrix[2][0], 0.0f) != 0) || (Tizen::Base::Float::Compare(matrix[2][1], 0.0f) != 0))
385         {
386                 return false;
387         }
388
389         return true;
390 }
391
392 bool
393 FloatMatrix3::IsInvertible(void) const
394 {
395         if (Tizen::Base::Float::Compare(GetDeterminant(), 0.0f) == 0)
396         {
397                 return false;
398         }
399
400         return true;
401 }
402
403 void
404 FloatMatrix3::Negate(void)
405 {
406         matrix[0][0] = -matrix[0][0];
407         matrix[0][1] = -matrix[0][1];
408         matrix[0][2] = -matrix[0][2];
409
410         matrix[1][0] = -matrix[1][0];
411         matrix[1][1] = -matrix[1][1];
412         matrix[1][2] = -matrix[1][2];
413
414         matrix[2][0] = -matrix[2][0];
415         matrix[2][1] = -matrix[2][1];
416         matrix[2][2] = -matrix[2][2];
417 }
418
419 void
420 FloatMatrix3::SetAsIdentity(void)
421 {
422         matrix[0][0] = 1.0f;
423         matrix[0][1] = 0.0f;
424         matrix[0][2] = 0.0f;
425
426         matrix[1][0] = 0.0f;
427         matrix[1][1] = 1.0f;
428         matrix[1][2] = 0.0f;
429
430         matrix[2][0] = 0.0f;
431         matrix[2][1] = 0.0f;
432         matrix[2][2] = 1.0f;
433 }
434
435 result
436 FloatMatrix3::Invert(void)
437 {
438         float a0 = matrix[1][1] * matrix[2][2] - matrix[2][1] * matrix[1][2];
439         float a1 = matrix[1][0] * matrix[2][2] - matrix[1][2] * matrix[2][0];
440         float a2 = matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0];
441
442         float determinant = matrix[0][0] * a0 - matrix[0][1] * a1 + matrix[0][2] * a2;
443
444         SysTryReturnResult(NID_BASE, Tizen::Base::Float::Compare(determinant, 0.0f) != 0, E_INVALID_OPERATION,
445                 "The current instance is not invertible.");
446
447         float inverseMatrix[3][3];
448
449         inverseMatrix[0][0] = (matrix[1][1] * matrix[2][2] - matrix[1][2] * matrix[2][1]) / determinant;
450         inverseMatrix[1][0] = (-matrix[1][0] * matrix[2][2] + matrix[1][2] * matrix[2][0]) / determinant;
451         inverseMatrix[2][0] = (matrix[1][0] * matrix[2][1] - matrix[1][1] * matrix[2][0]) / determinant;
452
453         inverseMatrix[0][1] = (-matrix[0][1] * matrix[2][2] + matrix[0][2] * matrix[2][1]) / determinant;
454         inverseMatrix[1][1] = (matrix[0][0] * matrix[2][2] - matrix[0][2] * matrix[2][0]) / determinant;
455         inverseMatrix[2][1] = (-matrix[0][0] * matrix[2][1] + matrix[0][1] * matrix[2][0]) / determinant;
456
457         inverseMatrix[0][2] = (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]) / determinant;
458         inverseMatrix[1][2] = (-matrix[0][0] * matrix[1][2] + matrix[0][2] * matrix[1][0]) / determinant;
459         inverseMatrix[2][2] = (matrix[0][0] * matrix[1][1] - matrix[0][1] * matrix[1][0]) / determinant;
460
461         memcpy(matrix, inverseMatrix, MATRIX_SIZE);
462
463         return E_SUCCESS;
464 }
465
466 void
467 FloatMatrix3::Transpose(void)
468 {
469         float tmp = 0.0f;
470         SWAP_VALUES(matrix[0][1], matrix[1][0], tmp);
471         SWAP_VALUES(matrix[0][2], matrix[2][0], tmp);
472
473         SWAP_VALUES(matrix[1][2], matrix[2][1], tmp);
474 }
475
476 void
477 FloatMatrix3::SetAsNull(void)
478 {
479         matrix[0][0] = 0.0f;
480         matrix[0][1] = 0.0f;
481         matrix[0][2] = 0.0f;
482
483         matrix[1][0] = 0.0f;
484         matrix[1][1] = 0.0f;
485         matrix[1][2] = 0.0f;
486
487         matrix[2][0] = 0.0f;
488         matrix[2][1] = 0.0f;
489         matrix[2][2] = 0.0f;
490 }
491
492 }} // Tizen::Base