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