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