Modify doxygen group names
[platform/core/uifw/dali-core.git] / dali / public-api / math / vector4.h
1 #ifndef __DALI_VECTOR_4_H__
2 #define __DALI_VECTOR_4_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
28 namespace Dali
29 {
30 /**
31  * @addtogroup dali_core_math
32  * @{
33  */
34
35 struct Vector2;
36 struct Vector3;
37
38 /**
39  * @brief A four dimensional vector.
40  *
41  * Components can be used as position or offset (x,y,z,w); color (r,g,b,a) or texture coords(s,t,p,q)
42  */
43 struct DALI_IMPORT_API Vector4
44 {
45 // NOTE
46 // xrs, ygt, zbp and waq must be consecutive in memory.
47 // No other data must be added before xrs member.
48 // No virtual methods must be added to this struct.
49
50 // Construction
51
52   /**
53    * @brief Default constructor, initializes the vector to 0.
54    */
55   Vector4()
56   : x(0.0f),
57     y(0.0f),
58     z(0.0f),
59     w(0.0f)
60   {
61   }
62
63   /**
64    * @brief Conversion constructor from four floats.
65    *
66    * @param [in] x (or r/s) component
67    * @param [in] y (or g/t) component
68    * @param [in] z (or b/p) component
69    * @param [in] w (or a/q) component
70    */
71   explicit Vector4(float x, float y, float z, float w)
72   : x(x),
73     y(y),
74     z(z),
75     w(w)
76   {
77   }
78
79
80   /**
81    * @brief Conversion constructor from an array of four floats.
82    *
83    * @param [in] array of either xyzw/rgba/stpq
84    */
85   explicit Vector4(const float* array)
86   : x(array[0]),
87     y(array[1]),
88     z(array[2]),
89     w(array[3])
90   {
91   }
92
93   /**
94    * @brief Conversion constructor from Vector2.
95    *
96    * @param [in] vec2 to copy from, z and w are initialized to 0
97    */
98   explicit Vector4( const Vector2& vec2 );
99
100   /**
101    * @brief Conversion constructor from Vector3.
102    *
103    * @param [in] vec3 to copy from, w is initialized to 0
104    */
105   explicit Vector4( const Vector3& vec3 );
106
107 // Constants
108   static const Vector4 ONE;   ///< (1.0f,1.0f,1.0f,1.0f)
109   static const Vector4 XAXIS; ///< (1.0f,0.0f,0.0f,0.0f)
110   static const Vector4 YAXIS; ///< (0.0f,1.0f,0.0f,0.0f)
111   static const Vector4 ZAXIS; ///< (0.0f,0.0f,1.0f,0.0f)
112   static const Vector4 ZERO;  ///< (0.0f, 0.0f, 0.0f, 0.0f)
113
114 // API
115
116   /**
117    * @brief Assignment operator.
118    *
119    * @param [in] array of floats
120    * @return itself
121    */
122   Vector4& operator=(const float* array)
123   {
124     x = array[0];
125     y = array[1];
126     z = array[2];
127     w = array[3];
128
129     return *this;
130   }
131
132   /**
133    * @brief Assignment operator.
134    *
135    * Only sets x and y. z and w are left as they were
136    * @param [in] vec2 to assign from.
137    * @return itself
138    */
139   Vector4& operator=(const Vector2& vec2 );
140
141   /**
142    * @brief Assignment operator.
143    *
144    * Only sets x and y and z. w is left as it was
145    * @param [in] vec3 to assign from
146    * @return itself
147    */
148   Vector4& operator=(const Vector3& vec3 );
149
150   /**
151    * @brief Addition operator.
152    *
153    * @param[in] rhs vector to add.
154    * @return A vector containing the result of the addition
155    */
156   Vector4 operator+(const Vector4 & rhs) const
157   {
158     Vector4 temp(*this);
159
160     return temp += rhs;
161   }
162
163   /**
164    * @brief Addition assignment operator.
165    *
166    * @param[in] rhs vector to add.
167    * @return itself
168    */
169   Vector4& operator+=(const Vector4& rhs)
170   {
171     x += rhs.x;
172     y += rhs.y;
173     z += rhs.z;
174     w += rhs.w;
175
176     return *this;
177   }
178
179   /**
180    * @brief Subtraction operator.
181    *
182    * @param[in] rhs  the vector to subtract
183    * @return A vector containing the result of the subtraction
184    */
185   Vector4 operator-(const Vector4& rhs) const
186   {
187     Vector4 temp(*this);
188
189     temp-=rhs;
190
191     return temp;
192   }
193
194   /**
195    * @brief Subtraction assignment operator.
196    *
197    * @param[in] rhs the vector to subtract
198    * @return itself
199    */
200   Vector4& operator-=(const Vector4& rhs)
201   {
202     x -= rhs.x;
203     y -= rhs.y;
204     z -= rhs.z;
205     w -= rhs.w;
206
207     return *this;
208   }
209
210   /**
211    * @brief Multiplication operator.
212    *
213    * @param[in] rhs the vector to multiply
214    * @return A vector containing the result of the multiplication
215    */
216   Vector4 operator*(const Vector4& rhs) const
217   {
218     Vector4 temp(*this);
219
220     return temp *= rhs;
221   }
222
223   /**
224    * @brief Multiplication operator.
225    *
226    * @param[in] rhs the float value to scale the vector
227    * @return A vector containing the result of the scaling
228    */
229   Vector4 operator*(float rhs) const
230   {
231     return Vector4(x * rhs, y * rhs, z * rhs, w * rhs);
232   }
233
234   /**
235    * @brief Multiplication assignment operator.
236    *
237    * @param[in] rhs the vector to multiply
238    * @return itself
239    */
240   Vector4& operator*=(const Vector4& rhs)
241   {
242     x *= rhs.x;
243     y *= rhs.y;
244     z *= rhs.z;
245     w *= rhs.w;
246
247     return *this;
248   }
249
250   /**
251    * @brief Multiplication assignment operator.
252    *
253    * @param[in] rhs the float value to scale the vector
254    * @return itself
255    */
256   Vector4& operator*=(float rhs)
257   {
258     x *= rhs;
259     y *= rhs;
260     z *= rhs;
261     w *= rhs;
262
263     return *this;
264   }
265
266   /**
267    * @brief Division operator.
268    *
269    * @param[in] rhs the vector to divide
270    * @return A vector containing the result of the division
271    */
272   Vector4 operator/(const Vector4 & rhs) const
273   {
274     Vector4 temp(*this);
275
276     return temp /= rhs;
277   }
278
279   /**
280    * @brief Division operator.
281    *
282    * @param[in] rhs The float value to scale the vector by
283    * @return A vector containing the result of the scaling
284    */
285   Vector4 operator/(float rhs) const
286   {
287     float oneOver = 1.0f / rhs;
288     return Vector4(x * oneOver, y * oneOver, z * oneOver, w * oneOver);
289   }
290
291   /**
292    * @brief Division assignment operator.
293    *
294    * @param[in] rhs the vector to divide
295    * @return itself
296    */
297   Vector4& operator/=(const Vector4& rhs)
298   {
299     x /= rhs.x;
300     y /= rhs.y;
301     z /= rhs.z;
302     w /= rhs.w;
303
304     return *this;
305   }
306
307   /**
308    * @brief Division assignment operator.
309    *
310    * @param[in] rhs the float value to scale the vector by
311    * @return itself
312    */
313   Vector4& operator/=(float rhs)
314   {
315     const float oneOver = 1.0f / rhs;
316     x *= oneOver;
317     y *= oneOver;
318     z *= oneOver;
319     w *= oneOver;
320
321     return *this;
322   }
323
324   /**
325    * @brief Unary negation operator.
326    *
327    * @return the negative value
328    */
329   Vector4 operator-() const
330   {
331     Vector4 temp(-x, -y, -z, -w);
332
333     return temp;
334   }
335
336   /**
337    * @brief Equality operator.
338    *
339    * Utilises appropriate machine epsilon values.
340    *
341    * @param[in] rhs The vector to test against
342    * @return true if the vectors are equal
343    */
344   bool operator==(const Vector4 &rhs) const;
345
346   /**
347    * @brief Inequality operator.
348    *
349    * Utilises appropriate machine epsilon values.
350    *
351    * @param[in] rhs The vector to test against
352    * @return true if the vectors are not equal
353    */
354   bool operator!=(const Vector4 &rhs) const
355   {
356     return !(*this == rhs);
357   }
358
359   /**
360    * @brief Const array subscript operator overload.
361    *
362    * Asserts if index is out of range. Should be 0, 1, 2 or 3
363    * @param[in] index Subscript
364    * @return    The float at the given index
365    */
366   const float& operator[](const unsigned int index) const
367   {
368     DALI_ASSERT_ALWAYS( index < 4 && "Vector element index out of bounds" );
369
370     return AsFloat()[index];
371   }
372
373   /**
374    * @brief Mutable array subscript operator overload.
375    *
376    * Asserts if index is out of range. Should be 0, 1, 2 or 3
377    * @param[in] index Subscript index
378    * @return    The float at the given index
379    */
380   float& operator[](const unsigned int index)
381   {
382     DALI_ASSERT_ALWAYS( index < 4 && "Vector element index out of bounds" );
383
384     return AsFloat()[index];
385   }
386
387   /**
388    * @brief Returns the dot product of this vector (4d) and another vector (3d).
389    *
390    * The dot product is the length of one vector in the direction of another vector.
391    * This is great for lighting, threshold testing the angle between two unit vectors,
392    * calculating the distance between two points in a particular direction.
393    * @param [in] other     the other vector
394    * @return               the dot product
395    */
396   float Dot(const Vector3& other) const;
397
398   /**
399    * @brief Returns the dot product of this vector and another vector.
400    *
401    * The dot product is the length of one vector in the direction of another vector.
402    * This is great for lighting, threshold testing the angle between two unit vectors,
403    * calculating the distance between two points in a particular direction.
404    * @param [in] other     the other vector
405    * @return               the dot product
406    */
407   float Dot(const Vector4& other) const;
408
409   /**
410    * @brief Returns the 4d dot product of this vector and another vector.
411    *
412    * @param [in] other     the other vector
413    * @return          the dot product
414    */
415   float Dot4(const Vector4& other) const;
416
417   /**
418    * @brief Returns the cross produce of this vector and another vector.
419    *
420    * The cross produce of two vectors is a vector which is perpendicular to the plane of the
421    * two vectors. This is great for calculating normals and making matrices orthogonal.
422    *
423    * @param [in] other    the other vector
424    * @return A vector containing the cross product
425    */
426   Vector4 Cross(const Vector4& other) const;
427
428   /**
429    * @brief Returns the length of the vector.
430    *
431    * @return the length.
432    */
433   float Length() const;
434
435   /**
436    * @brief Returns the length of the vector squared.
437    *
438    * This is faster than using Length() when performing
439    * threshold checks as it avoids use of the square root.
440    * @return the length of the vector squared.
441    */
442   float LengthSquared() const;
443
444   /**
445    * @brief Normalizes the vector.
446    *
447    * Sets the vector to unit length whilst maintaining its direction.
448    */
449   void Normalize();
450
451   /**
452    * @brief Clamps the vector between minimum and maximum vectors.
453    *
454    * @param [in] min the minimum vector
455    * @param [in] max the maximum vector
456    */
457   void Clamp( const Vector4& min, const Vector4& max );
458
459   /**
460    * @brief Returns the contents of the vector as an array of 4 floats.
461    *
462    * The order of the values in this array are as follows:
463    * 0: x (or r, or s)
464    * 1: y (or g, or t)
465    * 2: z (or b, or p)
466    * 3: w (or a, or q)
467    * @note inlined for performance reasons (generates less code than a function call)
468    * @return the vector contents as an array of 4 floats.
469    */
470   const float* AsFloat() const {return &x;}
471
472   /**
473    * @brief Returns the contents of the vector as an array of 4 floats.
474    *
475    * The order of the values in this array are as follows:
476    * 0: x (or r, or s)
477    * 1: y (or g, or t)
478    * 2: z (or b, or p)
479    * 3: w (or a, or q)
480    * @note inlined for performance reasons (generates less code than a function call)
481    * @return the vector contents as an array of 4 floats.
482    */
483   float* AsFloat() {return &x;}
484
485 // Data
486
487   // NOTE
488   // xrs, ygt, zbp and waq must be consecutive in memory.
489   // No other data must be added before xrs member.
490   // No virtual methods must be added to this struct.
491
492   union
493   {
494     float x; ///< x component
495     float r; ///< red component
496     float s; ///< s component
497   };
498   union
499   {
500     float y; ///< y component
501     float g; ///< green component
502     float t; ///< t component
503   };
504   union
505   {
506     float z; ///< z component
507     float b; ///< blue component
508     float p; ///< p component
509   };
510   union
511   {
512     float w; ///< w component
513     float a; ///< alpha component
514     float q; ///< q component
515   };
516 };
517
518 /**
519  * @brief Print a Vector4.
520  *
521  * @param [in] o The output stream operator.
522  * @param [in] vector The vector to print.
523  * @return The output stream operator.
524  */
525 DALI_IMPORT_API std::ostream& operator<<(std::ostream& o, const Vector4& vector);
526
527 /**
528  * @brief Returns a vector with components set to the minimum of the corresponding component in a and b.
529  *
530  * If a=0,1,2,3 and b=4,0,1,2  returns a vector of 0,0,1,2
531  * @param [in] a     a vector
532  * @param [in] b     a vector
533  * @return      a vector containing the minimum of each component from a and b
534  */
535 inline Vector4 Min( const Vector4& a, const Vector4& b )
536 {
537   return Vector4( a.x < b.x ? a.x : b.x,
538                   a.y < b.y ? a.y : b.y,
539                   a.z < b.z ? a.z : b.z,
540                   a.w < b.w ? a.w : b.w );
541 }
542
543 /**
544  * @brief Returns a vector with components set to the maximum of the corresponding component in a and b.
545  *
546  * If a=0,1,2,3 and b=4,0,1,2  returns a vector of 4,1,2,3
547  * @param [in] a     a vector
548  * @param [in] b     a vector
549  * @return      a vector containing the maximum of each component from a and b
550  */
551 inline Vector4 Max( const Vector4& a, const Vector4& b )
552 {
553   return Vector4( a.x > b.x ? a.x : b.x,
554                   a.y > b.y ? a.y : b.y,
555                   a.z > b.z ? a.z : b.z,
556                   a.w > b.w ? a.w : b.w );
557 }
558
559 /**
560  * @brief Clamps each of vector v's components between minimum and maximum values.
561  *
562  * @param [in] v     a vector
563  * @param [in] min the minimum value
564  * @param [in] max the maximum value
565  * @return     a vector containing the clamped components of v
566  */
567 DALI_IMPORT_API Vector4 Clamp( const Vector4& v, const float& min, const float& max );
568
569 // Allow Vector4 to be treated as a POD type
570 template <> struct TypeTraits< Vector4 > : public BasicTypes< Vector4 > { enum { IS_TRIVIAL_TYPE = true }; };
571
572 /**
573  * @}
574  */
575 } // namespace Dali
576
577 #endif // __DALI_VECTOR_4_H__