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