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