[dali_2.3.27] Merge branch '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) 2022 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 constexpr 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    * @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 uint32_t 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 uint32_t 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
511   {
512     return &x;
513   }
514
515   /**
516    * @brief Returns the contents of the vector as an array of 4 floats.
517    *
518    * @code
519    *
520    * The order of the values in this array are as follows:
521    * 0: x (or r, or s)
522    * 1: y (or g, or t)
523    * 2: z (or b, or p)
524    * 3: w (or a, or q)
525    *
526    * @endcode
527    *
528    * @SINCE_1_0.0
529    * @return The vector contents as an array of 4 floats
530    * @note inlined for performance reasons (generates less code than a function call)
531    */
532   float* AsFloat()
533   {
534     return &x;
535   }
536
537   // Data
538
539   // NOTE
540   // xrs, ygt, zbp and waq must be consecutive in memory.
541   // No other data must be added before xrs member.
542   // No virtual methods must be added to this struct.
543
544   union
545   {
546     float x; ///< x component
547     float r; ///< red component
548     float s; ///< s component
549   };
550   union
551   {
552     float y; ///< y component
553     float g; ///< green component
554     float t; ///< t component
555   };
556   union
557   {
558     float z; ///< z component
559     float b; ///< blue component
560     float p; ///< p component
561   };
562   union
563   {
564     float w; ///< w component
565     float a; ///< alpha component
566     float q; ///< q component
567   };
568
569 public:
570   Vector4(const Vector4&)     = default;            ///< Default copy constructor
571   Vector4(Vector4&&) noexcept = default;            ///< Default move constructor
572   Vector4& operator=(const Vector4&) = default;     ///< Default copy assignment operator
573   Vector4& operator=(Vector4&&) noexcept = default; ///< Default move assignment operator
574 };
575
576 /**
577  * @brief Print a Vector4.
578  *
579  * @SINCE_1_0.0
580  * @param[in] o The output stream operator
581  * @param[in] vector The vector to print
582  * @return The output stream operator
583  */
584 DALI_CORE_API std::ostream& operator<<(std::ostream& o, const Vector4& vector);
585
586 /**
587  * @brief Returns a vector with components set to the minimum of the corresponding component in a and b.
588  *
589  * If a=0,1,2,3 and b=4,0,1,2 returns a vector of 0,0,1,2.
590  * @SINCE_1_0.0
591  * @param[in] a A vector
592  * @param[in] b A vector
593  * @return A vector containing the minimum of each component from a and b
594  */
595 inline Vector4 Min(const Vector4& a, const Vector4& b)
596 {
597   return Vector4(a.x < b.x ? a.x : b.x,
598                  a.y < b.y ? a.y : b.y,
599                  a.z < b.z ? a.z : b.z,
600                  a.w < b.w ? a.w : b.w);
601 }
602
603 /**
604  * @brief Returns a vector with components set to the maximum of the corresponding component in a and b.
605  *
606  * If a=0,1,2,3 and b=4,0,1,2 returns a vector of 4,1,2,3.
607  * @SINCE_1_0.0
608  * @param[in] a A vector
609  * @param[in] b A vector
610  * @return A vector containing the maximum of each component from a and b
611  */
612 inline Vector4 Max(const Vector4& a, const Vector4& b)
613 {
614   return Vector4(a.x > b.x ? a.x : b.x,
615                  a.y > b.y ? a.y : b.y,
616                  a.z > b.z ? a.z : b.z,
617                  a.w > b.w ? a.w : b.w);
618 }
619
620 /**
621  * @brief Clamps each of vector v's components between minimum and maximum values.
622  *
623  * @SINCE_1_0.0
624  * @param[in] v A vector
625  * @param[in] min The minimum value
626  * @param[in] max The maximum value
627  * @return A vector containing the clamped components of v
628  */
629 DALI_CORE_API Vector4 Clamp(const Vector4& v, const float& min, const float& max);
630
631 // Allow Vector4 to be treated as a POD type
632 template<>
633 struct TypeTraits<Vector4> : public BasicTypes<Vector4>
634 {
635   enum
636   {
637     IS_TRIVIAL_TYPE = true
638   };
639 };
640
641 /**
642  * @}
643  */
644 } // namespace Dali
645
646 #endif // DALI_VECTOR_4_H