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