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