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