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