Making DALi public API typesafe using guaranteed types; uint8_t, uint32_t
[platform/core/uifw/dali-core.git] / dali / public-api / math / vector2.h
1 #ifndef __DALI_VECTOR_2_H__
2 #define __DALI_VECTOR_2_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 Vector3;
37 struct Vector4;
38
39 /**
40  * @brief A two dimensional vector.
41  * @SINCE_1_0.0
42  */
43 struct DALI_CORE_API Vector2
44 {
45 // (x width) and (y height) must be consecutive in memory.
46 // No other data must be added before (x width) member.
47 // No virtual methods must be added to this struct.
48
49 public:
50
51   /**
52    * @brief Constructor.
53    * @SINCE_1_0.0
54    */
55   Vector2()
56   : x(0.0f),
57     y(0.0f)
58   {
59   }
60
61   /**
62    * @brief Constructor.
63    *
64    * @SINCE_1_0.0
65    * @param[in] x x or width component
66    * @param[in] y y or height component
67    */
68   explicit Vector2(float x, float y)
69   : x(x), y(y)
70   {
71   }
72
73   /**
74    * @brief Conversion constructor from an array of two floats.
75    *
76    * @SINCE_1_0.0
77    * @param[in] array Array of xy
78    */
79   explicit Vector2(const float* array)
80   : x(array[0]),
81     y(array[1])
82   {
83   }
84
85   /**
86    * @brief Constructor.
87    *
88    * @SINCE_1_0.0
89    * @param[in] vec3 Vector3 to create this vector from
90    */
91   explicit Vector2(const Vector3& vec3);
92
93   /**
94    * @brief Constructor.
95    *
96    * @SINCE_1_0.0
97    * @param[in] vec4 Vector4 to create this vector from
98    */
99   explicit Vector2(const Vector4& vec4);
100
101 // Constants
102
103   static const Vector2 ONE;               ///< (1.0f,1.0f)
104   static const Vector2 XAXIS;             ///< Vector representing the X axis
105   static const Vector2 YAXIS;             ///< Vector representing the Y axis
106   static const Vector2 NEGATIVE_XAXIS;    ///< Vector representing the negative X axis
107   static const Vector2 NEGATIVE_YAXIS;    ///< Vector representing the negative Y axis
108   static const Vector2 ZERO;              ///< (0.0f, 0.0f)
109
110 // API
111
112   /**
113    * @brief Assignment operator.
114    *
115    * @SINCE_1_0.0
116    * @param[in] array Array of floats
117    * @return Itself
118    */
119   Vector2& operator=(const float* array)
120   {
121     x = array[0];
122     y = array[1];
123
124     return *this;
125   }
126
127   /**
128    * @brief Assignment operator.
129    *
130    * @SINCE_1_0.0
131    * @param[in] rhs Vector to assign
132    * @return Itself
133    */
134   Vector2& operator=(const Vector3& rhs);
135
136   /**
137    * @brief Assignment operator.
138    *
139    * @SINCE_1_0.0
140    * @param[in] rhs Vector to assign
141    * @return Itself
142    */
143   Vector2& operator=(const Vector4& rhs);
144
145   /**
146    * @brief Addition operator.
147    *
148    * @SINCE_1_0.0
149    * @param[in] rhs Vector to add
150    * @return A vector containing the result of the addition
151    */
152   Vector2 operator+(const Vector2& rhs) const
153   {
154     Vector2 temp(*this);
155
156     return temp += rhs;
157   }
158
159   /**
160    * @brief Addition assignment operator.
161    *
162    * @SINCE_1_0.0
163    * @param[in] rhs Vector to add
164    * @return Itself
165    */
166   Vector2& operator+=(const Vector2& rhs)
167   {
168     x += rhs.x;
169     y += rhs.y;
170
171     return *this;
172   }
173
174   /**
175    * @brief Subtraction operator.
176    *
177    * @SINCE_1_0.0
178    * @param[in] rhs The vector to subtract
179    * @return A vector containing the result of the subtraction
180    */
181   Vector2 operator-(const Vector2& rhs) const
182   {
183     Vector2 temp(*this);
184
185     return temp -= rhs;
186   }
187
188   /**
189    * @brief Subtraction assignment operator.
190    *
191    * @SINCE_1_0.0
192    * @param[in] rhs The vector to subtract
193    * @return Itself
194    */
195   Vector2& operator-=(const Vector2& rhs)
196   {
197     x -= rhs.x;
198     y -= rhs.y;
199
200     return *this;
201   }
202
203   /**
204    * @brief Multiplication operator.
205    *
206    * @SINCE_1_0.0
207    * @param[in] rhs The vector to multiply
208    * @return A vector containing the result of the multiplication
209    */
210   Vector2 operator*(const Vector2& rhs) const
211   {
212     return Vector2(x * rhs.x, y * rhs.y);
213   }
214
215   /**
216    * @brief Multiplication operator.
217    *
218    * @SINCE_1_0.0
219    * @param[in] rhs The float value to scale the vector
220    * @return A vector containing the result of the scaling
221    */
222   Vector2 operator*(float rhs) const
223   {
224     return Vector2(x * rhs, y * rhs);
225   }
226
227   /**
228    * @brief Multiplication assignment operator.
229    *
230    * @SINCE_1_0.0
231    * @param[in] rhs The vector to multiply
232    * @return Itself
233    */
234   Vector2& operator*=(const Vector2& rhs)
235   {
236     x *= rhs.x;
237     y *= rhs.y;
238
239     return *this;
240   }
241
242   /**
243    * @brief Multiplication assignment operator.
244    *
245    * @SINCE_1_0.0
246    * @param[in] rhs The float value to scale the vector
247    * @return Itself
248    */
249   Vector2& operator*=(float rhs)
250   {
251     x *= rhs;
252     y *= rhs;
253
254     return *this;
255   }
256
257   /**
258    * @brief Division operator.
259    *
260    * @SINCE_1_0.0
261    * @param[in] rhs The vector to divide
262    * @return A vector containing the result of the division
263    */
264   Vector2 operator/(const Vector2& rhs) const
265   {
266     return Vector2(x / rhs.x, y / rhs.y);
267   }
268
269   /**
270    * @brief Division operator.
271    *
272    * @SINCE_1_0.0
273    * @param[in] rhs The float value to scale the vector by
274    * @return A vector containing the result of the scaling
275    */
276   Vector2 operator/(float rhs) const
277   {
278     return Vector2(x / rhs, y / rhs);
279   }
280
281
282   /**
283    * @brief Division assignment operator.
284    *
285    * @SINCE_1_0.0
286    * @param[in] rhs The vector to divide
287    * @return Itself
288    */
289   Vector2& operator/=(const Vector2& rhs)
290   {
291     x /= rhs.x;
292     y /= rhs.y;
293
294     return *this;
295   }
296
297   /**
298    * @brief Division assignment operator.
299    *
300    * @SINCE_1_0.0
301    * @param[in] rhs The float value to scale the vector by
302    * @return Itself
303    */
304   Vector2& operator/=(float rhs)
305   {
306     x /= rhs;
307     y /= rhs;
308
309     return *this;
310   }
311
312   /**
313    * @brief Unary negation operator.
314    *
315    * @SINCE_1_0.0
316    * @return A vector containing the negation
317    */
318   Vector2 operator-() const
319   {
320     Vector2 temp(-x, -y);
321
322     return temp;
323   }
324
325   /**
326    * @brief Equality operator.
327    *
328    * Utilizes appropriate machine epsilon values.
329    *
330    * @SINCE_1_0.0
331    * @param[in] rhs The vector to test against
332    * @return true if the vectors are equal
333    */
334   bool operator==(const Vector2& rhs) const;
335
336   /**
337    * @brief Inequality operator.
338    *
339    * Utilizes appropriate machine epsilon values.
340    *
341    * @SINCE_1_0.0
342    * @param[in] rhs The vector to test against
343    * @return true if the vectors are not equal
344    */
345   bool operator!=(const Vector2& rhs) const
346   {
347     return !(*this == rhs);
348   }
349
350   /**
351    * @brief Const array subscript operator overload.
352    *
353    * Asserts if index is out of range. Should be 0 or 1.
354    * @SINCE_1_0.0
355    * @param[in] index Subscript index
356    * @return The float at the given index
357    */
358   const float& operator[](const uint32_t index) const
359   {
360     DALI_ASSERT_ALWAYS( index < 2 && "Vector element index out of bounds" );
361
362     return AsFloat()[index];
363   }
364
365   /**
366    * @brief Mutable array subscript operator overload.
367    *
368    * Asserts if index is out of range. Should be 0 or 1.
369    * @SINCE_1_0.0
370    * @param[in] index Subscript index
371    * @return The float at the given index
372    */
373   float& operator[](const uint32_t index)
374   {
375     DALI_ASSERT_ALWAYS( index < 2 && "Vector element index out of bounds" );
376
377     return AsFloat()[index];
378   }
379
380   /**
381    * @brief Returns the length of the vector.
382    *
383    * @SINCE_1_0.0
384    * @return The length of the vector
385    */
386   float Length() const;
387
388   /**
389    * @brief Returns the length of the vector squared.
390    *
391    * This is more efficient than Length() for threshold
392    * testing as it avoids the use of a square root.
393    * @SINCE_1_0.0
394    * @return The length of the vector squared
395    */
396   float LengthSquared() const;
397
398   /**
399    * @brief Sets the vector to be unit length, whilst maintaining its direction.
400    *
401    * @SINCE_1_0.0
402    */
403   void Normalize();
404
405   /**
406     * @brief Clamps the vector between minimum and maximum vectors.
407     *
408     * @SINCE_1_0.0
409     * @param[in] min The minimum vector
410     * @param[in] max The maximum vector
411    */
412   void Clamp( const Vector2& min, const Vector2& max );
413
414   /**
415    * @brief Returns the contents of the vector as an array of 2 floats.
416    *
417    * The order of the values in this array are as follows:
418    * 0: x (or width)
419    * 1: y (or height)
420    * @SINCE_1_0.0
421    * @return The vector contents as an array of 2 floats
422    * @note inlined for performance reasons (generates less code than a function call)
423    */
424   const float* AsFloat() const {return &x;}
425
426   /**
427    * @brief Returns the contents of the vector as an array of 2 floats.
428    *
429    * The order of the values in this array are as follows:
430    * 0: x (or width)
431    * 1: y (or height)
432    * @SINCE_1_0.0
433    * @return The vector contents as an array of 2 floats
434    * @note inlined for performance reasons (generates less code than a function call)
435    */
436   float* AsFloat() {return &x;}
437
438 public: // Data
439
440   // NOTE
441   // (x width) and (y height) must be consecutive in memory.
442   // No other data must be added before (x width) member.
443   // No virtual methods must be added to this struct.
444   union
445   {
446     float x;     ///< x component
447     float width; ///< width
448   };
449
450   union
451   {
452     float y;      ///< y component
453     float height; ///< height
454   };
455
456 };
457
458 /**
459  * @brief Size is an alias of Dali::Vector2.
460  * @SINCE_1_0.0
461  */
462 typedef Vector2 Size;
463
464 /**
465  * @brief Print a Vector2.
466  *
467  * @SINCE_1_0.0
468  * @param[in] o The output stream operator
469  * @param[in] vector The vector to print
470  * @return The output stream operator
471  */
472 DALI_CORE_API std::ostream& operator<< (std::ostream& o, const Vector2& vector);
473
474 /**
475  * @brief Returns a vector with components set to the minimum of the corresponding component in a and b.
476  *
477  * If a=0,1 and b=1,0 returns a vector of 0,0.
478  * @SINCE_1_0.0
479  * @param[in] a A vector
480  * @param[in] b A vector
481  * @return A vector containing the minimum of each component from a and b
482  */
483 inline Vector2 Min( const Vector2& a, const Vector2& b )
484 {
485   return Vector2( a.x < b.x ? a.x : b.x , a.y < b.y ? a.y : b.y );
486 }
487
488 /**
489  * @brief Returns a vector with components set to the maximum of the corresponding component in a and b.
490  *
491  * If a=0,1 and b=1,0 returns a vector of 1,1.
492  * @SINCE_1_0.0
493  * @param[in] a A vector
494  * @param[in] b A vector
495  * @return A vector containing the maximum of each component from a and b
496  */
497 inline Vector2 Max( const Vector2& a, const Vector2& b )
498 {
499   return Vector2( a.x > b.x ? a.x : b.x , a.y > b.y ? a.y : b.y );
500 }
501
502 /**
503  * @brief Clamps each of vector v's components between minimum and maximum values.
504  *
505  * @SINCE_1_0.0
506  * @param[in] v A vector
507  * @param[in] min The minimum value
508  * @param[in] max The maximum value
509  * @return A vector containing the clamped components of v
510  */
511 DALI_CORE_API Vector2 Clamp( const Vector2& v, const float& min, const float& max );
512
513 // Allow Vector2 to be treated as a POD type
514 template <> struct TypeTraits< Vector2 > : public BasicTypes< Vector2 > { enum { IS_TRIVIAL_TYPE = true }; };
515
516 /**
517  * @}
518  */
519 } // namespace Dali
520
521 #endif // __DALI_VECTOR_2_H__