[4.0] Fast bounding-box clipping feature
[platform/core/uifw/dali-core.git] / dali / public-api / math / matrix.h
1 #ifndef __DALI_MATRIX_H__
2 #define __DALI_MATRIX_H__
3
4 /*
5  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <iosfwd>
23
24 // INTERNAL INCLUDES
25 #include <dali/public-api/common/dali-common.h>
26 #include <dali/public-api/common/type-traits.h>
27 #include <dali/public-api/math/vector4.h>
28
29 namespace Dali
30 {
31 /**
32  * @addtogroup dali_core_math
33  * @{
34  */
35
36 class Vector2;
37 class Quaternion;
38
39 /**
40  * @brief The Matrix class represents transformations and projections.
41  *
42  * It is agnostic w.r.t. row/column major notation - it operates on a flat array.
43  * Each axis is contiguous in memory, so the x axis corresponds to elements 0, 1, 2 and 3, the y axis corresponds to elements 4, 5, 6, 7, etc.
44  * @SINCE_1_0.0
45  */
46 class DALI_IMPORT_API Matrix
47 {
48 public:
49
50   friend std::ostream& operator<< (std::ostream& o, const Matrix& matrix);
51
52   /**
53    * @brief Constructor.
54    *
55    * Zero initializes the matrix.
56    * @SINCE_1_0.0
57    */
58   Matrix();
59
60   /**
61    * @brief Constructor.
62    *
63    * @SINCE_1_0.0
64    * @param[in] initialize True for initialization by zero or otherwise
65    */
66   explicit Matrix( bool initialize );
67
68   /**
69    * @brief Constructor.
70    *
71    * The matrix is initialized with the contents of 'array' which must contain 16 floats.
72    * The order of the values for a transform matrix is:
73    *
74    * @code
75    *
76    *   xAxis.x xAxis.y xAxis.z 0.0f
77    *   yAxis.x yAxis.y yAxis.z 0.0f
78    *   zAxis.x zAxis.y zAxis.z 0.0f
79    *   trans.x trans.y trans.z 1.0f
80    *
81    * @endcode
82    *
83    * @SINCE_1_0.0
84    * @param[in] array Pointer of 16 floats data
85    */
86   explicit Matrix(const float* array);
87
88   /**
89    * @brief Constructs a matrix from quaternion.
90    *
91    * @SINCE_1_0.0
92    * @param rotation Rotation as quaternion
93    */
94   explicit Matrix( const Quaternion& rotation );
95
96   /**
97    * @brief Copy constructor.
98    *
99    * @SINCE_1_0.0
100    * @param[in] matrix A reference to the copied matrix
101    */
102   Matrix( const Matrix& matrix );
103
104   /**
105    * @brief Assignment operator.
106    *
107    * @SINCE_1_0.0
108    * @param[in] matrix A reference to the copied matrix
109    * @return A reference to this
110    */
111   Matrix& operator=( const Matrix& matrix );
112
113   /**
114    * @brief The identity matrix.
115    */
116   static const Matrix IDENTITY;
117
118   /**
119    * @brief Sets this matrix to be an identity matrix.
120    * @SINCE_1_0.0
121    */
122   void SetIdentity();
123
124   /**
125    * @brief Sets this matrix to be an identity matrix with scale.
126    *
127    * @SINCE_1_0.0
128    * @param[in] scale Scale to set on top of identity matrix
129    */
130   void SetIdentityAndScale( const Vector3& scale );
131
132   /**
133    * @brief Inverts a transform Matrix.
134    *
135    * Any Matrix representing only a rotation and/or translation
136    * can be inverted using this function. It is faster and more accurate then using Invert().
137    * @SINCE_1_0.0
138    * @param[out] result The inverse of this matrix
139    */
140   void InvertTransform(Matrix& result) const;
141
142   /**
143    * @brief Generic brute force Matrix Invert.
144    *
145    * Using the Matrix invert function for the specific type
146    * of matrix you are dealing with is faster, more accurate.
147    * @SINCE_1_0.0
148    * @return True if successful
149    */
150   bool Invert();
151
152   /**
153    * @brief Swaps the rows to columns.
154    * @SINCE_1_0.0
155    */
156   void Transpose();
157
158   /**
159    * @brief Returns the xAxis from a Transform matrix.
160    *
161    * @SINCE_1_0.0
162    * @return The x axis
163    */
164   Vector3 GetXAxis() const;
165
166   /**
167    * @brief Returns the yAxis from a Transform matrix.
168    *
169    * @SINCE_1_0.0
170    * @return The y axis
171    */
172   Vector3 GetYAxis() const;
173
174   /**
175    * @brief Returns the zAxis from a Transform matrix.
176    *
177    * @SINCE_1_0.0
178    * @return The z axis
179    */
180   Vector3 GetZAxis() const;
181
182   /**
183    * @brief Sets the x axis.
184    *
185    * This assumes the matrix is a transform matrix.
186    * @SINCE_1_0.0
187    * @param[in] axis The values to set the axis to
188    */
189   void SetXAxis(const Vector3& axis);
190
191   /**
192    * @brief Sets the y axis.
193    *
194    * This assumes the matrix is a transform matrix.
195    * @SINCE_1_0.0
196    * @param[in] axis The values to set the axis to
197    */
198   void SetYAxis(const Vector3& axis);
199
200   /**
201    * @brief Sets the z axis.
202    *
203    * This assumes the matrix is a transform matrix.
204    * @SINCE_1_0.0
205    * @param[in] axis The values to set the axis to
206    */
207   void SetZAxis(const Vector3& axis);
208
209   /**
210    * @brief Gets the translation.
211    *
212    * This assumes the matrix is a transform matrix.
213    * @SINCE_1_0.0
214    * @return The translation
215    * @note inlined for performance reasons (generates less code than a function call)
216    */
217   const Vector4& GetTranslation() const { return reinterpret_cast<const Vector4&>(mMatrix[12]); }
218
219   /**
220    * @brief Gets the x,y and z components of the translation as a Vector3.
221    *
222    * This assumes the matrix is a transform matrix.
223    * @SINCE_1_0.0
224    * @return The translation
225    * @note inlined for performance reasons (generates less code than a function call)
226    */
227   const Vector3& GetTranslation3() const { return reinterpret_cast<const Vector3&>(mMatrix[12]); }
228
229   /**
230    * @brief Sets the translation.
231    *
232    * This assumes the matrix is a transform matrix.
233    * @SINCE_1_0.0
234    * @param[in] translation The translation
235    */
236   void SetTranslation(const Vector4& translation);
237
238   /**
239    * @brief Sets the x,y and z components of the translation from a Vector3.
240    *
241    * This assumes the matrix is a transform matrix.
242    * @SINCE_1_0.0
243    * @param[in] translation The translation
244    */
245   void SetTranslation(const Vector3& translation);
246
247   /**
248    * @brief Makes the axes of the matrix orthogonal to each other and of unit length.
249    *
250    * This function is used to correct floating point errors which would otherwise accumulate
251    * as operations are applied to the matrix. This function assumes the matrix is a transform
252    * matrix.
253    * @SINCE_1_0.0
254    */
255   void OrthoNormalize();
256
257   /**
258    * @brief Returns the contents of the matrix as an array of 16 floats.
259    *
260    * The order of the values for a transform matrix is:
261    *
262    * @code
263    *
264    *   xAxis.x xAxis.y xAxis.z 0.0f
265    *   yAxis.x yAxis.y yAxis.z 0.0f
266    *   zAxis.x zAxis.y zAxis.z 0.0f
267    *   trans.x trans.y trans.z 1.0f
268    *
269    * @endcode
270    *
271    * @SINCE_1_0.0
272    * @return The matrix contents as an array of 16 floats
273    * @note inlined for performance reasons (generates less code than a function call)
274    */
275   const float* AsFloat() const {return mMatrix;}
276
277   /**
278    * @brief Returns the contents of the matrix as an array of 16 floats.
279    *
280    * The order of the values for a transform matrix is:
281    *
282    * @code
283    *
284    *   xAxis.x xAxis.y xAxis.z 0.0f
285    *   yAxis.x yAxis.y yAxis.z 0.0f
286    *   zAxis.x zAxis.y zAxis.z 0.0f
287    *   trans.x trans.y trans.z 1.0f
288    *
289    * @endcode
290    *
291    * @SINCE_1_0.0
292    * @return The matrix contents as an array of 16 floats
293    * @note inlined for performance reasons (generates less code than a function call)
294    */
295   float* AsFloat() {return mMatrix;}
296
297   /**
298    * @brief Function to multiply two matrices and store the result onto third.
299    *
300    * Use this method in time critical path as it does not require temporaries.
301    * @SINCE_1_0.0
302    * @param[out] result Result of the multiplication
303    * @param[in] lhs Matrix, this can be same matrix as result
304    * @param[in] rhs Matrix, this cannot be same matrix as result
305    */
306   static void Multiply( Matrix& result, const Matrix& lhs, const Matrix& rhs );
307
308   /**
309    * @brief Function to multiply a matrix and quaternion and store the result onto third.
310    *
311    * Use this method in time critical path as it does not require temporaries.
312    * @SINCE_1_0.0
313    * @param[out] result Result of the multiplication
314    * @param[in] lhs Matrix, this can be same matrix as result
315    * @param[in] rhs Quaternion
316    */
317   static void Multiply( Matrix& result, const Matrix& lhs, const Quaternion& rhs );
318
319   /**
320    * @brief The multiplication by Vector4 operator.
321    *
322    * @SINCE_1_0.0
323    * @param[in] rhs The Vector4 coordinates to multiply this matrix by
324    * @return A Vector4 containing the result coordinates
325    */
326   Vector4 operator*(const Vector4& rhs) const;
327
328   /**
329    * @brief The multiplication by Vector2 operator.
330    * Note: This performs an optimized 2D transformation.
331    *
332    * @SINCE_1_2.59
333    * @param[in] rhs The Vector2 coordinates to multiply this matrix by
334    * @return A Vector2 containing the result coordinates
335    */
336   Vector2 operator*( const Vector2& rhs ) const;
337
338   /**
339    * @brief The equality operator.
340    *
341    * Utilizes appropriate machine epsilon values.
342    *
343    * @SINCE_1_0.0
344    * @param[in] rhs The Matrix to compare this to
345    * @return true if the matrices are equal
346    */
347   bool operator==(const Matrix & rhs) const;
348
349   /**
350    * @brief The inequality operator.
351    *
352    * Utilizes appropriate machine epsilon values.
353    * @SINCE_1_0.0
354    * @param[in] rhs The Matrix to compare this to
355    * @return true if the matrices are not equal.
356    */
357   bool operator!=(const Matrix & rhs) const;
358
359   /**
360    * @brief Sets this matrix to contain the position, scale and rotation components.
361    *
362    * Performs scale, rotation, then translation
363    * @SINCE_1_0.0
364    * @param[in] scale Scale to apply
365    * @param[in] rotation Rotation to apply
366    * @param[in] translation Translation to apply
367    */
368   void SetTransformComponents(const Vector3& scale,
369                               const Quaternion& rotation,
370                               const Vector3& translation );
371
372   /**
373    * @brief Sets this matrix to contain the inverse of the position, scale and rotation components.
374    *
375    * Performs translation, then rotation, then scale.
376    * @SINCE_1_0.0
377    * @param[in] scale Scale to apply
378    * @param[in] rotation Rotation to apply
379    * @param[in] translation Translation to apply
380    */
381   void SetInverseTransformComponents(const Vector3&    scale,
382                                      const Quaternion& rotation,
383                                      const Vector3&    translation );
384
385
386   /**
387    * @brief Sets this matrix to contain the inverse of the orthonormal basis and position components.
388    *
389    * Performs translation, then rotation.
390    * @SINCE_1_0.0
391    * @param[in] xAxis The X axis of the basis
392    * @param[in] yAxis The Y axis of the basis
393    * @param[in] zAxis The Z axis of the basis
394    * @param[in] translation Translation to apply
395    */
396   void SetInverseTransformComponents(const Vector3&    xAxis,
397                                      const Vector3&    yAxis,
398                                      const Vector3&    zAxis,
399                                      const Vector3&    translation );
400
401   /**
402    * @brief Gets the position, scale and rotation components from the given transform matrix.
403    *
404    * @SINCE_1_0.0
405    * @param[out] position Position to set
406    * @param[out] rotation Rotation to set - only valid if the transform matrix has not been skewed or sheared
407    * @param[out] scale Scale to set - only valid if the transform matrix has not been skewed or sheared
408    * @pre This matrix must not contain skews or shears.
409    */
410   void GetTransformComponents(Vector3& position,
411                               Quaternion& rotation,
412                               Vector3& scale) const;
413
414 private:
415
416   float mMatrix[16]; ///< The elements of the matrix
417 };
418
419 /**
420  * @brief Prints a matrix.
421  *
422  * It is printed in memory order, i.e. each printed row is contiguous in memory.
423  * @SINCE_1_0.0
424  * @param[in] o The output stream operator
425  * @param[in] matrix The matrix to print
426  * @return The output stream operator
427  */
428 DALI_IMPORT_API std::ostream& operator<< (std::ostream& o, const Matrix& matrix);
429
430 // Allow Matrix to be treated as a POD type
431 template <> struct TypeTraits< Matrix > : public BasicTypes< Matrix > { enum { IS_TRIVIAL_TYPE = true }; };
432
433 /**
434  * @}
435  */
436 } // namespace Dali
437
438 #endif // __DALI_MATRIX_H__