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