Gamedev Framework (gf)  0.3.0
A C++11 framework for 2D games
Vector.h
1 /*
2  * Gamedev Framework (gf)
3  * Copyright (C) 2016 Julien Bernard
4  *
5  * This software is provided 'as-is', without any express or implied
6  * warranty. In no event will the authors be held liable for any damages
7  * arising from the use of this software.
8  *
9  * Permission is granted to anyone to use this software for any purpose,
10  * including commercial applications, and to alter it and redistribute it
11  * freely, subject to the following restrictions:
12  *
13  * 1. The origin of this software must not be misrepresented; you must not
14  * claim that you wrote the original software. If you use this software
15  * in a product, an acknowledgment in the product documentation would be
16  * appreciated but is not required.
17  * 2. Altered source versions must be plainly marked as such, and must not be
18  * misrepresented as being the original software.
19  * 3. This notice may not be removed or altered from any source distribution.
20  */
21 #ifndef GF_VECTOR_H
22 #define GF_VECTOR_H
23 
24 #include <cstddef>
25 #include <cstdint>
26 
27 #include <algorithm>
28 #include <initializer_list>
29 #include <type_traits>
30 
31 #include "Portability.h"
32 
33 namespace gf {
34 #ifndef DOXYGEN_SHOULD_SKIP_THIS
35 inline namespace v1 {
36 #endif
37 
38  /**
39  * @ingroup core
40  * @brief General purpose math vector
41  *
42  * gf::Vector is a class that represents an element of a `N`-dimensional
43  * space. It is used throughout the library for different purposes.
44  *
45  * The template parameter `T` is the type of coordinates. . It can be any
46  * type that supports arithmetic operations (+, -, *, /) and relational
47  * operators (==, !=, <, >).
48  *
49  * Several specializations are defined for common use cases:
50  *
51  * - For dimension 2: gf::Vector<T, 2>
52  * - For dimension 3: gf::Vector<T, 3>
53  * - For dimension 4: gf::Vector<T, 4>
54  *
55  * This class was designed according to the article
56  * [On Vector Math Libraries](http://www.reedbeta.com/blog/2013/12/28/on-vector-math-libraries/)
57  * by Nathan Reed.
58  */
59  template<typename T, std::size_t N>
60  struct Vector {
61  #ifndef DOXYGEN_SHOULD_SKIP_THIS
62  static_assert(N > 0, "N must be strictly positive");
63  #endif
64 
65  /**
66  * @brief Default constructor
67  *
68  * This constructor is defaulted so that this type is
69  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
70  */
71  Vector() = default;
72 
73  /**
74  * @brief Constructor that fills the vector with a value.
75  *
76  * This constructor takes a value and fills the entire vector with this
77  * value. Care must be taken when calling this constructor:
78  *
79  * ~~~{.cc}
80  * gf::Vector<int, 5> vecOK(42); // OK, vector is filled with 42
81  * gf::Vector<int, 5> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
82  * ~~~
83  *
84  * @param val The value to fill the vector with
85  */
86  explicit Vector(T val)
87  {
88  std::fill_n(data, N, val);
89  }
90 
91  /**
92  * @brief Constructor that takes an array
93  *
94  * This constructor can ease conversion from other math libraries. The
95  * array must contain enough data for `N` dimensions.
96  *
97  * ~~~{.cc}
98  * float array[5] = { 1.0f, -1.0f, 0.5f, -2.0f, 0.0f };
99  * gf::Vector<float, 5> vec(array);
100  * ~~~
101  *
102  * @param array An array with the values of the vector
103  */
104  explicit Vector(T *array)
105  {
106  std::copy_n(array, N, data);
107  }
108 
109  /**
110  * @brief Constructor that takes an initializer list
111  *
112  * This constructor allows to use an initializer list to define the
113  * coordinates of the vector.
114  *
115  * ~~~{.cc}
116  * gf::Vector<bool, 5> vec1{ true, true, false, true, false };
117  * gf::Vector<bool, 5> vec2 = { false, true, true, false, true };
118  * ~~~
119  *
120  * @param list An initializer list.
121  */
122  Vector(std::initializer_list<T> list)
123  {
124  std::copy_n(list.begin(), std::min(list.size(), N), data);
125  }
126 
127  /**
128  * @brief Default copy constructor
129  *
130  * This constructor is defaulted so that this type is
131  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
132  *
133  * @param other The vector to copy from
134  */
135  Vector(const Vector& other) = default;
136 
137 
138  /**
139  * @brief Converting copy constructor
140  *
141  * @param other The vector to copy from
142  */
143  template<typename U>
144  Vector(const Vector<U, N>& other)
145  {
146  static_assert(std::is_convertible<U,T>::value, "");
147  std::transform(data, data + N, other.data, [](U val) { return static_cast<T>(val); });
148  }
149 
150  /**
151  * @brief Default copy assignment
152  *
153  * This operator is defaulted so that this type is
154  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
155  */
156  Vector& operator=(const Vector& other) = default;
157 
158  /**
159  * @brief Access to the @f$ i @f$-th coordinate.
160  *
161  * ~~~{.cc}
162  * gf::Vector<int, 5> vec = { 1, 3, 5, 7, 9 };
163  * std::printf("%i", vec[1]); // prints 3
164  * ~~~
165  *
166  * @param i the coordinate number
167  * @return The @f$ i @f$-th coordinate of the vector
168  */
169  T operator[](std::size_t i) const {
170  return data[i];
171  }
172 
173  /**
174  * @brief Access to the @f$ i @f$-th coordinate.
175  *
176  * ~~~{.cc}
177  * gf::Vector<int, 5> vec;
178  * vec[0] = vec[1] = vec[2] = vec[3] = vec[4] = 0;
179  * ~~~
180  *
181  * @param i the coordinate number
182  * @return The @f$ i @f$-th coordinate of the vector
183  */
184  T& operator[](std::size_t i) {
185  return data[i];
186  }
187 
188 
189  /**
190  * @brief Iterator.to the first element.
191  *
192  * @return A pointer to the first element.
193  */
194  inline
195  T *begin(void) {
196  return &(data[0]);
197  }
198 
199  /**
200  * @brief Iterator to the element after the last one.
201  *
202  * @return An invalid pointer that is the adress after the last element.
203  */
204  inline
205  T *end(void) {
206  return &(data[N]);
207  }
208 
209  /**
210  * @brief Iterator.to the first element (const version).
211  *
212  * @return A pointer on the first const element.
213  */
214  inline
215  T const *begin(void) const {
216  return &(data[0]);
217  }
218 
219  /**
220  * @brief Iterator on the element after the last one (const version).
221  *
222  * @return An invalid pointer that is the adress after the last const
223  * element.
224  */
225  inline
226  T const *end(void) const {
227  return &(data[N]);
228  }
229  /**
230  * @brief Iterator.on the first element (const version).
231  *
232  * @return A pointer on the first const element.
233  */
234  inline
235  T const *cbegin(void) const {
236  return &(data[0]);
237  }
238 
239  /**
240  * @brief Iterator on the element after the last one (const version).
241  *
242  * @return An invalid pointer that is the adress after the last const
243  * element.
244  */
245  inline
246  T const *cend(void) const {
247  return &(data[N]);
248  }
249 
250  /**
251  * @brief The internal representation of the vector
252  *
253  * A vector is represented with an array of `N` values of type `T`. It
254  * can be accessed directly, like an array or like a pointer, which can
255  * ease interoperability with other libraries.
256  */
257  T data[N];
258  };
259 
260  /**
261  * @ingroup core
262  * @brief A 2D vector
263  *
264  * This specialization of gf::Vector handles the 2-dimension spaces. It can
265  * be accessed with various representations:
266  *
267  * - the generic representation with the `data` member
268  * - the `(x,y)` representation, used for generic coordinates in the 2D space
269  * - the `(u,v)` representation, used for texture coordinates (see [UV mapping](https://en.wikipedia.org/wiki/UV_mapping))
270  * - the `(s,t)` representation, used for texture coordinates
271  * - the size representation with a `width` member and a `height` member, used to represent a 2-dimensional size
272  * - the indices representation with a `col` member and a `row` member, used to access a 2-dimensional array (gf::Array2D)
273  *
274  * Several common typedef are defined:
275  *
276  * - gf::Vector2i with `int` as `T`
277  * - gf::Vector2u with `unsigned` as `T`
278  * - gf::Vector2z with `std::size_t` as `T`
279  * - gf::Vector2f with `float` as `T`
280  * - gf::Vector2d with `double` as `T`
281  * - gf::Vector2b with `bool` as `T`
282  *
283  * Usage example:
284  *
285  * ~~~{.cc}
286  * gf::Vector2f v1(16.5f, 24.0f);
287  * v1.x = 18.2f;
288  *
289  * gf::Vector2f v2 = v1 * 5.0f;
290  * gf::Vector2f v3 = v1 + v2;
291  *
292  * bool different = (v2 != v3);
293  *
294  * gf::Vector2u size;
295  * size.width = 1920;
296  * size.height = 1080;
297  *
298  * gf::Vector2f texCoords;
299  * texCoords.u = 0.0f;
300  * texCoords.v = 0.3f;
301  * ~~~
302  */
303  template <typename T>
304  struct Vector<T, 2> {
305  /**
306  * @brief Default constructor
307  *
308  * This constructor is defaulted so that this type is
309  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
310  */
311  Vector() = default;
312 
313  /**
314  * @brief Constructor that fills the vector with a value.
315  *
316  * This constructor takes a value and fills the entire vector with this
317  * value. Care must be taken when calling this constructor:
318  *
319  * ~~~{.cc}
320  * gf::Vector<int, 2> vecOK(42); // OK, vector is filled with 42
321  * gf::Vector<int, 2> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
322  * ~~~
323  *
324  * @param val The value to fill the vector with
325  */
326  explicit Vector(T val) {
327  std::fill_n(data, 2, val);
328  }
329 
330  /**
331  * @brief Constructor that takes an array
332  *
333  * This constructor can ease conversion from other math libraries. The
334  * array must contain enough data for 2 dimensions.
335  *
336  * ~~~{.cc}
337  * float array[2] = { 1.0f, -1.0f };
338  * gf::Vector<float, 2> vec(array);
339  * ~~~
340  *
341  * @param array An array with the values of the vector
342  */
343  explicit Vector(T *array)
344  {
345  std::copy_n(array, 2, data);
346  }
347 
348  /**
349  * @brief Constructor that takes 2 components
350  *
351  * @param x The first component
352  * @param y The second component
353  */
354  constexpr Vector(T x, T y)
355  : data{ x, y }
356  {
357 
358  }
359 
360  /**
361  * @brief Default copy constructor
362  *
363  * This constructor is defaulted so that this type is
364  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
365  *
366  * @param other The vector to copy from
367  */
368  Vector(const Vector& other) = default;
369 
370 
371  /**
372  * @brief Converting copy constructor
373  *
374  * @param other The vector to copy from
375  */
376  template<typename U>
377  Vector(const Vector<U, 2>& other)
378  : x(other.x)
379  , y(other.y)
380  {
381 
382  }
383 
384  /**
385  * @brief Access to the @f$ i @f$-th coordinate.
386  *
387  * ~~~{.cc}
388  * gf::Vector<int, 2> vec = { 1, 3 };
389  * std::printf("%i", vec[1]); // prints 3
390  * ~~~
391  *
392  * @param i the coordinate number
393  * @return The @f$ i @f$-th coordinate of the vector
394  */
395  T operator[](std::size_t i) const {
396  return data[i];
397  }
398 
399  /**
400  * @brief Access to the @f$ i @f$-th coordinate.
401  *
402  * ~~~{.cc}
403  * gf::Vector<int, 2> vec;
404  * vec[0] = vec[1] = 0;
405  * ~~~
406  *
407  * @param i the coordinate number
408  * @return The @f$ i @f$-th coordinate of the vector
409  */
410  T& operator[](std::size_t i) {
411  return data[i];
412  }
413 
414 
415  /**
416  * @brief Iterator.to the first element.
417  *
418  * @return A pointer to the first element.
419  */
420  inline
421  T *begin(void) {
422  return &(data[0]);
423  }
424 
425  /**
426  * @brief Iterator to the element after the last one.
427  *
428  * @return An invalid pointer that is the adress after the last element.
429  */
430  inline
431  T *end(void) {
432  return &(data[2]);
433  }
434 
435  /**
436  * @brief Iterator.to the first element (const version).
437  *
438  * @return A pointer on the first const element.
439  */
440  inline
441  T const *begin(void) const {
442  return &(data[0]);
443  }
444 
445  /**
446  * @brief Iterator on the element after the last one (const version).
447  *
448  * @return An invalid pointer that is the adress after the last const
449  * element.
450  */
451  inline
452  T const *end(void) const {
453  return &(data[2]);
454  }
455  /**
456  * @brief Iterator.on the first element (const version).
457  *
458  * @return A pointer on the first const element.
459  */
460  inline
461  T const *cbegin(void) const {
462  return &(data[0]);
463  }
464 
465  /**
466  * @brief Iterator on the element after the last one (const version).
467  *
468  * @return An invalid pointer that is the adress after the last const
469  * element.
470  */
471  inline
472  T const *cend(void) const {
473  return &(data[2]);
474  }
475 
476  /**
477  * An anonymous union to handle the various representations
478  */
479  union {
480  T data[2]; ///< Generic representation
481  struct {
482  T x; ///< First coordinate in the `(x,y)` representation. @sa y
483  T y; ///< Second coordinate in the `(x,y)` representation. @sa x
484  };
485  struct {
486  T u; ///< First coordinate in the `(u,v)` representation. @sa v
487  T v; ///< Second coordinate in the `(u,v)` representation. @sa u
488  };
489  struct {
490  T s; ///< First coordinate in the `(s,t)` representation. @sa t
491  T t; ///< Second coordinate in the `(s,t)` representation. @sa s
492  };
493  struct {
494  T width; ///< First coordinate in the size representation. @sa height
495  T height; ///< Second coordinate in the size representation. @sa width
496  };
497  struct {
498  T col; ///< First coordinate in the indices representation @sa row
499  T row; ///< Second coordinate in the indices representation @sa col
500  };
501  };
502  };
503 
504  /**
505  * @ingroup core
506  * @brief A 3D vector
507  *
508  * This specialization of gf::Vector handles the 3-dimension spaces. It can
509  * be accessed with various representations:
510  *
511  * - the generic representation with the `data` member
512  * - the `(x,y,z)` representation, used for generic coordinates in the 3D space
513  * - the `(r,g,b)` representation, used for RGB colors
514  *
515  * Several common typedef are defined:
516  *
517  * - gf::Vector3i with `int` as `T`
518  * - gf::Vector3u with `unsigned` as `T`
519  * - gf::Vector3z with `std::size_t` as `T`
520  * - gf::Vector3f with `float` as `T`
521  * - gf::Vector3d with `double` as `T`
522  * - gf::Vector3b with `bool` as `T`
523  *
524  * For colors, some additional typedef are defined:
525  *
526  * - gf::Color3f with `float` as `T`
527  * - gf::Color3u with `uint8_t` as `T`
528  *
529  * Usage example:
530  *
531  * ~~~{.cc}
532  * gf::Vector3f v1(58.0f, 96.0f, 63.0f);
533  * v1.x = 94.0f;
534  *
535  * gf::Vector3f v2 = v1 * 5.0f;
536  * gf::Vector3f v3 = v1 + v2;
537  *
538  * gf::Color3u green(0x00, 0xFF, 0x00);
539  * ~~~
540  */
541  template <typename T>
542  struct Vector<T, 3> {
543  /**
544  * @brief Default constructor
545  *
546  * This constructor is defaulted so that this type is
547  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
548  */
549  Vector() = default;
550 
551  /**
552  * @brief Constructor that fills the vector with a value.
553  *
554  * This constructor takes a value and fills the entire vector with this
555  * value. Care must be taken when calling this constructor:
556  *
557  * ~~~{.cc}
558  * gf::Vector<int, 3> vecOK(42); // OK, vector is filled with 42
559  * gf::Vector<int, 3> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
560  * ~~~
561  *
562  * @param val The value to fill the vector with
563  */
564  explicit Vector(T val) {
565  std::fill_n(data, 3, val);
566  }
567 
568  /**
569  * @brief Constructor that takes an array
570  *
571  * This constructor can ease conversion from other math libraries. The
572  * array must contain enough data for 3 dimensions.
573  *
574  * ~~~{.cc}
575  * float array[3] = { 1.0f, -1.0f, 0.0f };
576  * gf::Vector<float, 3> vec(array);
577  * ~~~
578  *
579  * @param array An array with the values of the vector
580  */
581  explicit Vector(T *array)
582  {
583  std::copy_n(array, 3, data);
584  }
585 
586  /**
587  * @brief Constructor that takes 3 components
588  *
589  * @param x The first component
590  * @param y The second component
591  * @param z The third component
592  */
593  constexpr Vector(T x, T y, T z)
594  : data{ x, y, z }
595  {
596 
597  }
598 
599  /**
600  * @brief Constructor that takes a 2D vector and a z component
601  *
602  * @param xy The first 2 component, x and y
603  * @param z The z component
604  */
605  constexpr Vector(Vector<T, 2> xy, T z)
606  : data{ xy.x, xy.y, z }
607  {
608 
609  }
610 
611  /**
612  * @brief Default copy constructor
613  *
614  * This constructor is defaulted so that this type is
615  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
616  *
617  * @param other The vector to copy from
618  */
619  Vector(const Vector& other) = default;
620 
621 
622  /**
623  * @brief Converting copy constructor
624  *
625  * @param other The vector to copy from
626  */
627  template<typename U>
628  Vector(const Vector<U, 3>& other)
629  : x(other.x)
630  , y(other.y)
631  , z(other.z)
632  {
633 
634  }
635 
636  /**
637  * @brief Access to the @f$ i @f$-th coordinate.
638  *
639  * ~~~{.cc}
640  * gf::Vector<int, 3> vec = { 1, 3, 5 };
641  * std::printf("%i", vec[1]); // prints 3
642  * ~~~
643  *
644  * @param i the coordinate number
645  * @return The @f$ i @f$-th coordinate of the vector
646  */
647  T operator[](std::size_t i) const {
648  return data[i];
649  }
650 
651  /**
652  * @brief Access to the @f$ i @f$-th coordinate.
653  *
654  * ~~~{.cc}
655  * gf::Vector<int, 3> vec;
656  * vec[0] = vec[1] = vec[2] = 0;
657  * ~~~
658  *
659  * @param i the coordinate number
660  * @return The @f$ i @f$-th coordinate of the vector
661  */
662  T& operator[](std::size_t i) {
663  return data[i];
664  }
665 
666 
667  /**
668  * @brief Iterator.to the first element.
669  *
670  * @return A pointer to the first element.
671  */
672  inline
673  T *begin(void) {
674  return &(data[0]);
675  }
676 
677  /**
678  * @brief Iterator to the element after the last one.
679  *
680  * @return An invalid pointer that is the adress after the last element.
681  */
682  inline
683  T *end(void) {
684  return &(data[3]);
685  }
686 
687  /**
688  * @brief Iterator.to the first element (const version).
689  *
690  * @return A pointer on the first const element.
691  */
692  inline
693  T const *begin(void) const {
694  return &(data[0]);
695  }
696 
697  /**
698  * @brief Iterator on the element after the last one (const version).
699  *
700  * @return An invalid pointer that is the adress after the last const
701  * element.
702  */
703  inline
704  T const *end(void) const {
705  return &(data[3]);
706  }
707  /**
708  * @brief Iterator.on the first element (const version).
709  *
710  * @return A pointer on the first const element.
711  */
712  inline
713  T const *cbegin(void) const {
714  return &(data[0]);
715  }
716 
717  /**
718  * @brief Iterator on the element after the last one (const version).
719  *
720  * @return An invalid pointer that is the adress after the last const
721  * element.
722  */
723  inline
724  T const *cend(void) const {
725  return &(data[3]);
726  }
727 
728  /**
729  * An anonymous union to handle the various representations
730  */
731  union {
732  T data[3]; ///< Generic representation
733  struct {
734  T x; ///< First coordinate in the `(x,y,z)` representation. @sa y, z
735  T y; ///< Second coordinate in the `(x,y,z)` representation. @sa x, z
736  T z; ///< Third coordinate in the `(x,y,z)` representation. @sa x, y
737  };
738  struct {
739  T r; ///< First coordinate in the `(r,g,b)` representation. @sa g, b
740  T g; ///< Second coordinate in the `(r,g,b)` representation. @sa r, b
741  T b; ///< Third coordinate in the `(r,g,b)` representation. @sa r, g
742  };
743  Vector<T, 2> xy; ///< Swizzle to get the first two coordinates as a 2D vector
744  };
745  };
746 
747  /**
748  * @ingroup core
749  * @brief A 4D vector
750  *
751  * This specialization of gf::Vector handles the 4-dimension spaces. It can
752  * be accessed with various representations:
753  *
754  * - the generic representation with the `data` member
755  * - the `(x,y,z,w)` representation, used for generic coordinates in the 4D space
756  * - the `(r,g,b,a)` representation, used for RGBA colors
757  *
758  * Several common typedef are defined:
759  *
760  * - gf::Vector4i with `int` as `T`
761  * - gf::Vector4u with `unsigned` as `T`
762  * - gf::Vector4z with `std::size_t` as `T`
763  * - gf::Vector4f with `float` as `T`
764  * - gf::Vector4d with `double` as `T`
765  * - gf::Vector4b with `bool` as `T`
766  *
767  * For colors, some additional typedef are defined:
768  *
769  * - gf::Color4f with `float` as `T`
770  * - gf::Color4u with `uint8_t` as `T`
771  *
772  * Usage example:
773  *
774  * ~~~{.cc}
775  * gf::Vector4f v1(98.0f, 75.0f, 23.0f);
776  * v1.x = 57.0f;
777  *
778  * gf::Vector4f v2 = v1 * 5.0f;
779  * gf::Vector4f v3 = v1 + v2;
780  *
781  * gf::Color4u opaqueGreen(0x00, 0xFF, 0x00, 0xFF);
782  * ~~~
783  */
784  template <typename T>
785  struct Vector<T, 4> {
786  /**
787  * @brief Default constructor
788  *
789  * This constructor is defaulted so that this type is
790  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
791  */
792  Vector() = default;
793 
794  /**
795  * @brief Constructor that fills the vector with a value.
796  *
797  * This constructor takes a value and fills the entire vector with this
798  * value. Care must be taken when calling this constructor:
799  *
800  * ~~~{.cc}
801  * gf::Vector<int, 4> vecOK(42); // OK, vector is filled with 42
802  * gf::Vector<int, 4> vecKO{42}; // KO, vector is initialized with a 42 in the first coordinate
803  * ~~~
804  *
805  * @param val The value to fill the vector with
806  */
807  explicit Vector(T val) {
808  std::fill_n(data, 4, val);
809  }
810 
811  /**
812  * @brief Constructor that takes an array
813  *
814  * This constructor can ease conversion from other math libraries. The
815  * array must contain enough data for 4 dimensions.
816  *
817  * ~~~{.cc}
818  * float array[4] = { 1.0f, -1.0f, 0.5f, 0.0f };
819  * gf::Vector<float, 4> vec(array);
820  * ~~~
821  *
822  * @param array An array with the values of the vector
823  */
824  explicit Vector(T *array)
825  {
826  std::copy_n(array, 4, data);
827  }
828 
829  /**
830  * @brief Constructor that takes 4 components
831  *
832  * @param x The first component
833  * @param y The second component
834  * @param z The third component
835  * @param w The fourth component
836  */
837  constexpr Vector(T x, T y, T z, T w)
838  : data{ x, y, z, w }
839  {
840 
841  }
842 
843  /**
844  * @brief Default copy constructor
845  *
846  * This constructor is defaulted so that this type is
847  * [trivial](http://en.cppreference.com/w/cpp/concept/TrivialType).
848  *
849  * @param other The vector to copy from
850  */
851  Vector(const Vector& other) = default;
852 
853 
854  /**
855  * @brief Converting copy constructor
856  *
857  * @param other The vector to copy from
858  */
859  template<typename U>
860  Vector(const Vector<U, 4>& other)
861  : x(other.x)
862  , y(other.y)
863  , z(other.z)
864  , w(other.w)
865  {
866 
867  }
868 
869  /**
870  * @brief Access to the @f$ i @f$-th coordinate.
871  *
872  * ~~~{.cc}
873  * gf::Vector<int, 4> vec = { 1, 3, 5, 7 };
874  * std::printf("%i", vec[1]); // prints 3
875  * ~~~
876  *
877  * @param i the coordinate number
878  * @return The @f$ i @f$-th coordinate of the vector
879  */
880  T operator[](std::size_t i) const {
881  return data[i];
882  }
883 
884  /**
885  * @brief Access to the @f$ i @f$-th coordinate.
886  *
887  * ~~~{.cc}
888  * gf::Vector<int, 5> vec;
889  * vec[0] = vec[1] = vec[2] = vec[3] = vec[4] = 0;
890  * ~~~
891  *
892  * @param i the coordinate number
893  * @return The @f$ i @f$-th coordinate of the vector
894  */
895  T& operator[](std::size_t i) {
896  return data[i];
897  }
898 
899 
900  /**
901  * @brief Iterator.to the first element.
902  *
903  * @return A pointer to the first element.
904  */
905  inline
906  T *begin(void) {
907  return &(data[0]);
908  }
909 
910  /**
911  * @brief Iterator to the element after the last one.
912  *
913  * @return An invalid pointer that is the adress after the last element.
914  */
915  inline
916  T *end(void) {
917  return &(data[4]);
918  }
919 
920  /**
921  * @brief Iterator.to the first element (const version).
922  *
923  * @return A pointer on the first const element.
924  */
925  inline
926  T const *begin(void) const {
927  return &(data[0]);
928  }
929 
930  /**
931  * @brief Iterator on the element after the last one (const version).
932  *
933  * @return An invalid pointer that is the adress after the last const
934  * element.
935  */
936  inline
937  T const *end(void) const {
938  return &(data[4]);
939  }
940  /**
941  * @brief Iterator.on the first element (const version).
942  *
943  * @return A pointer on the first const element.
944  */
945  inline
946  T const *cbegin(void) const {
947  return &(data[0]);
948  }
949 
950  /**
951  * @brief Iterator on the element after the last one (const version).
952  *
953  * @return An invalid pointer that is the adress after the last const
954  * element.
955  */
956  inline
957  T const *cend(void) const {
958  return &(data[4]);
959  }
960 
961  /**
962  * An anonymous union to handle the various representations
963  */
964  union {
965  T data[4]; ///< Generic representation
966  struct {
967  T x; ///< First coordinate in the `(x,y,z,w)` representation. @sa y, z, w
968  T y; ///< Second coordinate in the `(x,y,z,w)` representation. @sa x, z, w
969  T z; ///< Third coordinate in the `(x,y,z,w)` representation. @sa x, y, w
970  T w; ///< Fourth coordinate in the `(x,y,z,w)` representation. @sa x, y, z
971  };
972  struct {
973  T r; ///< First coordinate in the `(r,g,b,a)` representation. @sa g, b, a
974  T g; ///< Second coordinate in the `(r,g,b,a)` representation. @sa r, b, a
975  T b; ///< Third coordinate in the `(r,g,b,a)` representation. @sa r, g, a
976  T a; ///< Fourth coordinate in the `(r,g,b,a)` representation. @sa r, g, b
977  };
978  Vector<T, 2> xy; ///< Swizzle to get the first two coordinates as a 2D vector
979  Vector<T, 3> xyz; ///< Swizzle to get the first three coordinates as a 3D vector
980  Vector<T, 3> rgb; ///< Swizzle to get the first three coordinates as a RGB color
981  };
982  };
983 
984  /**
985  * @ingroup core
986  * @brief A float vector with 2 components
987  */
988  using Vector2f = Vector<float, 2>;
989 
990  /**
991  * @ingroup core
992  * @brief A float vector with 3 components
993  */
994  using Vector3f = Vector<float, 3>;
995 
996  /**
997  * @ingroup core
998  * @brief A float vector with 4 components
999  */
1000  using Vector4f = Vector<float, 4>;
1001 
1002  /**
1003  * @ingroup core
1004  * @brief A double vector with 2 components
1005  */
1006  using Vector2d = Vector<double, 2>;
1007 
1008  /**
1009  * @ingroup core
1010  * @brief A double vector with 3 components
1011  */
1012  using Vector3d = Vector<double, 3>;
1013 
1014  /**
1015  * @ingroup core
1016  * @brief A double vector with 4 components
1017  */
1018  using Vector4d = Vector<double, 4>;
1019 
1020  /**
1021  * @ingroup core
1022  * @brief A int vector with 2 components
1023  */
1024  using Vector2i = Vector<int, 2>;
1025 
1026  /**
1027  * @ingroup core
1028  * @brief A int vector with 3 components
1029  */
1030  using Vector3i = Vector<int, 3>;
1031 
1032  /**
1033  * @ingroup core
1034  * @brief A int vector with 4 components
1035  */
1036  using Vector4i = Vector<int, 4>;
1037 
1038  /**
1039  * @ingroup core
1040  * @brief A unsigned vector with 2 components
1041  */
1042  using Vector2u = Vector<unsigned, 2>;
1043 
1044  /**
1045  * @ingroup core
1046  * @brief A unsigned vector with 3 components
1047  */
1048  using Vector3u = Vector<unsigned, 3>;
1049 
1050  /**
1051  * @ingroup core
1052  * @brief A unsigned vector with 4 components
1053  */
1054  using Vector4u = Vector<unsigned, 4>;
1055 
1056  /**
1057  * @ingroup core
1058  * @brief A std::size_t vector with 2 components
1059  */
1060  using Vector2z = Vector<std::size_t, 2>;
1061 
1062  /**
1063  * @ingroup core
1064  * @brief A std::size_t vector with 3 components
1065  */
1066  using Vector3z = Vector<std::size_t, 3>;
1067 
1068  /**
1069  * @ingroup core
1070  * @brief A std::size_t vector with 4 components
1071  */
1072  using Vector4z = Vector<std::size_t, 4>;
1073 
1074  /**
1075  * @ingroup core
1076  * @brief A bool vector with 2 components
1077  */
1078  using Vector2b = Vector<bool, 2>;
1079 
1080  /**
1081  * @ingroup core
1082  * @brief A bool vector with 3 components
1083  */
1084  using Vector3b = Vector<bool, 3>;
1085 
1086  /**
1087  * @ingroup core
1088  * @brief A bool vector with 4 components
1089  */
1090  using Vector4b = Vector<bool, 4>;
1091 
1092  /**
1093  * @ingroup core
1094  * @brief A float color vector with 3 components
1095  */
1096  using Color3f = Vector<float, 3>;
1097 
1098  /**
1099  * @ingroup core
1100  * @brief A float color vector with 4 components
1101  */
1102  using Color4f = Vector<float, 4>;
1103 
1104  /**
1105  * @ingroup core
1106  * @brief A uint8_t color vector with 3 components
1107  */
1108  using Color3u = Vector<uint8_t, 3>;
1109 
1110  /**
1111  * @ingroup core
1112  * @brief A uint8_t color vector with 4 components
1113  */
1114  using Color4u = Vector<uint8_t, 4>;
1115 
1116 // MSVC does not like extern template
1117 #ifndef _MSC_VER
1118  extern template struct Vector<float, 2>;
1119  extern template struct Vector<float, 3>;
1120  extern template struct Vector<float, 4>;
1121 
1122  extern template struct Vector<double, 2>;
1123  extern template struct Vector<double, 3>;
1124  extern template struct Vector<double, 4>;
1125 
1126  extern template struct Vector<int, 2>;
1127  extern template struct Vector<int, 3>;
1128  extern template struct Vector<int, 4>;
1129 
1130  extern template struct Vector<unsigned, 2>;
1131  extern template struct Vector<unsigned, 3>;
1132  extern template struct Vector<unsigned, 4>;
1133 
1134  extern template struct Vector<bool, 2>;
1135  extern template struct Vector<bool, 3>;
1136  extern template struct Vector<bool, 4>;
1137 
1138  extern template struct Vector<uint8_t, 3>;
1139  extern template struct Vector<uint8_t, 4>;
1140 #endif
1141 
1142  /**
1143  * @ingroup core
1144  * @brief A distance function
1145  *
1146  * A distance function is a function that gives the distance between two vectors.
1147  *
1148  * ~~~
1149  * gf::Distance<float, 3> distFn = gf::manhattanDistance<float, 3>;
1150  * Vector3f vec1 = ...;
1151  * Vector3f vec2 = ...;
1152  *
1153  * float distance = distFn(vec1, vec2);
1154  * ~~~
1155  *
1156  * @sa manhattanDistance(), squareDistance(), euclideanDistance(), chebyshevDistance()
1157  * @sa gf::Distance2, gf::Distance3
1158  */
1159  template<typename T, std::size_t N>
1160  using Distance = T (*)(const Vector<T, N>&, const Vector<T, N>&);
1161 
1162  /**
1163  * @ingroup core
1164  * @brief A distance function for 2D vectors
1165  *
1166  * @sa gf::Distance
1167  */
1168  template<typename T>
1169  using Distance2 = Distance<T, 2>;
1170 
1171  /**
1172  * @ingroup core
1173  * @brief A distance function for 3D vectors
1174  *
1175  * @sa gf::Distance
1176  */
1177  template<typename T>
1178  using Distance3 = Distance<T, 3>;
1179 
1180 #ifndef DOXYGEN_SHOULD_SKIP_THIS
1181 }
1182 #endif
1183 }
1184 
1185 #endif // GAME_VECTOR_H
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:581
T const * end(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:226
T const * cbegin(void) const
Iterator.on the first element (const version).
Definition: Vector.h:946
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:564
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:662
T const * cend(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:724
T * begin(void)
Iterator.to the first element.
Definition: Vector.h:906
T const * cend(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:957
constexpr Vector(T x, T y)
Constructor that takes 2 components.
Definition: Vector.h:354
friend class RenderTarget
Definition: Shader.h:387
T const * end(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:452
T const * end(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:937
Vector()=default
Default constructor.
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:895
T const * begin(void) const
Iterator.to the first element (const version).
Definition: Vector.h:215
constexpr Vector(T x, T y, T z)
Constructor that takes 3 components.
Definition: Vector.h:593
T const * cbegin(void) const
Iterator.on the first element (const version).
Definition: Vector.h:713
T data[N]
The internal representation of the vector.
Definition: Vector.h:257
T const * begin(void) const
Iterator.to the first element (const version).
Definition: Vector.h:693
constexpr Vector(T x, T y, T z, T w)
Constructor that takes 4 components.
Definition: Vector.h:837
T const * cbegin(void) const
Iterator.on the first element (const version).
Definition: Vector.h:461
Definition: Action.h:34
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:184
T const * cend(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:246
Vector & operator=(const Vector &other)=default
Default copy assignment.
T * begin(void)
Iterator.to the first element.
Definition: Vector.h:195
Vector(const Vector &other)=default
Default copy constructor.
T const * end(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:704
T const * begin(void) const
Iterator.to the first element (const version).
Definition: Vector.h:926
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:647
T * end(void)
Iterator to the element after the last one.
Definition: Vector.h:431
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:880
T * end(void)
Iterator to the element after the last one.
Definition: Vector.h:916
Vector()=default
Default constructor.
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:395
T & operator[](std::size_t i)
Access to the -th coordinate.
Definition: Vector.h:410
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:824
constexpr Vector(Vector< T, 2 > xy, T z)
Constructor that takes a 2D vector and a z component.
Definition: Vector.h:605
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:343
Vector(const Vector &other)=default
Default copy constructor.
Vector(const Vector< U, 3 > &other)
Converting copy constructor.
Definition: Vector.h:628
Vector()=default
Default constructor.
T const * cend(void) const
Iterator on the element after the last one (const version).
Definition: Vector.h:472
Vector(const Vector &other)=default
Default copy constructor.
T const * begin(void) const
Iterator.to the first element (const version).
Definition: Vector.h:441
Vector(const Vector< U, 4 > &other)
Converting copy constructor.
Definition: Vector.h:860
T operator[](std::size_t i) const
Access to the -th coordinate.
Definition: Vector.h:169
T const * cbegin(void) const
Iterator.on the first element (const version).
Definition: Vector.h:235
Vector(const Vector< U, N > &other)
Converting copy constructor.
Definition: Vector.h:144
Vector(const Vector &other)=default
Default copy constructor.
T * begin(void)
Iterator.to the first element.
Definition: Vector.h:673
General purpose math vector.
Definition: Vector.h:60
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:86
Vector(std::initializer_list< T > list)
Constructor that takes an initializer list.
Definition: Vector.h:122
Vector(const Vector< U, 2 > &other)
Converting copy constructor.
Definition: Vector.h:377
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:326
T * end(void)
Iterator to the element after the last one.
Definition: Vector.h:205
T * begin(void)
Iterator.to the first element.
Definition: Vector.h:421
Vector()=default
Default constructor.
T * end(void)
Iterator to the element after the last one.
Definition: Vector.h:683
Vector(T *array)
Constructor that takes an array.
Definition: Vector.h:104
Vector(T val)
Constructor that fills the vector with a value.
Definition: Vector.h:807