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