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