Mathter
A configurable 3D math library for game developers.
VectorArithmetic.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include "VectorImpl.hpp"
4 
5 
6 namespace mathter {
7 
9 template <class T, int Dim, bool Packed>
12  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
13  for (int i = 0; i < Dim; ++i) {
14  result[i] = lhs.data[i] * rhs.data[i];
15  }
16  }
17  else {
18  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
19  result.simd = SimdT::mul(lhs.simd, rhs.simd);
20  }
21  return result;
22 }
24 template <class T, int Dim, bool Packed>
27  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
28  for (int i = 0; i < Dim; ++i) {
29  result[i] = lhs.data[i] / rhs.data[i];
30  }
31  }
32  else {
33  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
34  result.simd = SimdT::div(lhs.simd, rhs.simd);
35  }
36  return result;
37 }
39 template <class T, int Dim, bool Packed>
42  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
43  for (int i = 0; i < Dim; ++i) {
44  result[i] = lhs.data[i] + rhs.data[i];
45  }
46  }
47  else {
48  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
49  result.simd = SimdT::add(lhs.simd, rhs.simd);
50  }
51  return result;
52 }
54 template <class T, int Dim, bool Packed>
57  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
58  for (int i = 0; i < Dim; ++i) {
59  result[i] = lhs.data[i] - rhs.data[i];
60  }
61  }
62  else {
63  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
64  result.simd = SimdT::sub(lhs.simd, rhs.simd);
65  }
66  return result;
67 }
68 
69 // Vector assign arithmetic
71 template <class T, int Dim, bool Packed>
73  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
74  for (int i = 0; i < Dim; ++i) {
75  lhs.data[i] *= rhs.data[i];
76  }
77  }
78  else {
79  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
80  lhs.simd = SimdT::mul(lhs.simd, rhs.simd);
81  }
82  return lhs;
83 }
84 
86 template <class T, int Dim, bool Packed>
88  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
89  for (int i = 0; i < Dim; ++i) {
90  lhs.data[i] /= rhs.data[i];
91  }
92  }
93  else {
94  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
95  lhs.simd = SimdT::div(lhs.simd, rhs.simd);
96  }
97  return lhs;
98 }
99 
101 template <class T, int Dim, bool Packed>
103  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
104  for (int i = 0; i < Dim; ++i) {
105  lhs.data[i] += rhs.data[i];
106  }
107  }
108  else {
109  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
110  lhs.simd = SimdT::add(lhs.simd, rhs.simd);
111  }
112  return lhs;
113 }
114 
116 template <class T, int Dim, bool Packed>
118  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
119  for (int i = 0; i < Dim; ++i) {
120  lhs.data[i] -= rhs.data[i];
121  }
122  }
123  else {
124  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
125  lhs.simd = SimdT::sub(lhs.simd, rhs.simd);
126  }
127  return lhs;
128 }
129 
130 // Scalar assign arithmetic
132 template <class T, int Dim, bool Packed>
134  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
135  for (int i = 0; i < Dim; ++i) {
136  lhs.data[i] *= rhs;
137  }
138  }
139  else {
140  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
141  lhs.simd = SimdT::mul(lhs.simd, rhs);
142  }
143  return lhs;
144 }
145 
147 template <class T, int Dim, bool Packed>
149  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
150  for (int i = 0; i < Dim; ++i) {
151  lhs.data[i] /= rhs;
152  }
153  }
154  else {
155  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
156  lhs.simd = SimdT::div(lhs.simd, rhs);
157  }
158  return lhs;
159 }
160 
162 template <class T, int Dim, bool Packed>
164  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
165  for (int i = 0; i < Dim; ++i) {
166  lhs.data[i] += rhs;
167  }
168  }
169  else {
170  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
171  lhs.simd = SimdT::add(lhs.simd, rhs);
172  }
173  return lhs;
174 }
175 
177 template <class T, int Dim, bool Packed>
179  if constexpr (!traits::HasSimd<Vector<T, Dim, Packed>>::value) {
180  for (int i = 0; i < Dim; ++i) {
181  lhs.data[i] -= rhs;
182  }
183  }
184  else {
185  using SimdT = decltype(VectorData<T, Dim, Packed>::simd);
186  lhs.simd = SimdT::sub(lhs.simd, rhs);
187  }
188  return lhs;
189 }
190 
191 
193 template <class T, int Dim, bool Packed>
195  Vector<T, Dim, Packed> copy(lhs);
196  copy *= rhs;
197  return copy;
198 }
200 template <class T, int Dim, bool Packed>
202  Vector<T, Dim, Packed> copy(lhs);
203  copy /= rhs;
204  return copy;
205 }
207 template <class T, int Dim, bool Packed>
209  Vector<T, Dim, Packed> copy(lhs);
210  copy += rhs;
211  return copy;
212 }
214 template <class T, int Dim, bool Packed>
216  Vector<T, Dim, Packed> copy(lhs);
217  copy -= rhs;
218  return copy;
219 }
220 
221 
223 template <class T, int Dim, bool Packed, class U, class = typename std::enable_if<std::is_convertible<U, T>::value>::type>
224 inline Vector<T, Dim, Packed> operator*(U lhs, const Vector<T, Dim, Packed>& rhs) { return rhs * (T)lhs; }
226 template <class T, int Dim, bool Packed, class U, class = typename std::enable_if<std::is_convertible<U, T>::value>::type>
227 inline Vector<T, Dim, Packed> operator+(U lhs, const Vector<T, Dim, Packed>& rhs) { return rhs + (T)lhs; }
229 template <class T, int Dim, bool Packed, class U, class = typename std::enable_if<std::is_convertible<U, T>::value>::type>
230 inline Vector<T, Dim, Packed> operator-(U lhs, const Vector<T, Dim, Packed>& rhs) { return Vector<T, Dim, Packed>(lhs) - rhs; }
232 template <class T, int Dim, bool Packed, class U, class = typename std::enable_if<std::is_convertible<U, T>::value>::type>
234  Vector<T, Dim, Packed> copy(lhs);
235  copy /= rhs;
236  return copy;
237 }
238 
239 
241 template <class T, int Dim, bool Packed>
243  return a * b + c;
244 }
245 
247 template <class T, int Dim, bool Packed>
249  return arg * T(-1);
250 }
251 
253 template <class T, int Dim, bool Packed>
255  return arg;
256 }
257 
258 //------------------------------------------------------------------------------
259 // Swizzle ops
260 //------------------------------------------------------------------------------
261 
262 template <class T, int Dim, bool Packed, int... Indices>
263 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>> operator*(const Vector<T, Dim, Packed>& v, const Swizzle<T, Indices...>& s) {
264  return v * decltype(v)(s);
265 }
266 
267 template <class T, int Dim, bool Packed, int... Indices>
268 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>> operator/(const Vector<T, Dim, Packed>& v, const Swizzle<T, Indices...>& s) {
269  return v / decltype(v)(s);
270 }
271 
272 template <class T, int Dim, bool Packed, int... Indices>
273 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>> operator+(const Vector<T, Dim, Packed>& v, const Swizzle<T, Indices...>& s) {
274  return v + decltype(v)(s);
275 }
276 
277 template <class T, int Dim, bool Packed, int... Indices>
278 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>> operator-(const Vector<T, Dim, Packed>& v, const Swizzle<T, Indices...>& s) {
279  return v - decltype(v)(s);
280 }
281 
282 
283 
284 template <class T, int Dim, bool Packed, int... Indices>
285 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>> operator*(const Swizzle<T, Indices...>& s, const Vector<T, Dim, Packed>& v) {
286  return decltype(v)(s) * v;
287 }
288 
289 template <class T, int Dim, bool Packed, int... Indices>
290 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>> operator/(const Swizzle<T, Indices...>& s, const Vector<T, Dim, Packed>& v) {
291  return decltype(v)(s) / v;
292 }
293 
294 template <class T, int Dim, bool Packed, int... Indices>
295 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>> operator+(const Swizzle<T, Indices...>& s, const Vector<T, Dim, Packed>& v) {
296  return decltype(v)(s) + v;
297 }
298 
299 template <class T, int Dim, bool Packed, int... Indices>
300 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>> operator-(const Swizzle<T, Indices...>& s, const Vector<T, Dim, Packed>& v) {
301  return decltype(v)(s) - v;
302 }
303 
304 
305 
306 template <class T, int Dim, bool Packed, int... Indices>
307 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>>& operator*=(const Vector<T, Dim, Packed>& v, const Swizzle<T, Indices...>& s) {
308  return v *= decltype(v)(s);
309 }
310 
311 template <class T, int Dim, bool Packed, int... Indices>
312 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>>& operator/=(const Vector<T, Dim, Packed>& v, const Swizzle<T, Indices...>& s) {
313  return v /= decltype(v)(s);
314 }
315 
316 template <class T, int Dim, bool Packed, int... Indices>
317 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>>& operator+=(const Vector<T, Dim, Packed>& v, const Swizzle<T, Indices...>& s) {
318  return v += decltype(v)(s);
319 }
320 
321 template <class T, int Dim, bool Packed, int... Indices>
322 std::enable_if_t<Dim == sizeof...(Indices), Vector<T, Dim, Packed>>& operator-=(const Vector<T, Dim, Packed>& v, const Swizzle<T, Indices...>& s) {
323  return v -= decltype(v)(s);
324 }
325 
326 
327 
328 } // namespace mathter
Matrix< U, Rows, Columns, Order1, Layout1, Packed > & operator+=(Matrix< T, Rows, Columns, Order1, Layout1, Packed > &lhs, const Matrix< U, Rows, Columns, Order2, Layout2, Packed > &rhs)
Performs matrix addition and stores result in this.
Definition: MatrixArithmetic.hpp:287
Vector< T, Dim, Packed > MultiplyAdd(const Vector< T, Dim, Packed > &a, const Vector< T, Dim, Packed > &b, const Vector< T, Dim, Packed > &c)
Return (a*b)+c. Performs MAD or FMA if supported by target architecture.
Definition: VectorArithmetic.hpp:242
auto operator*(const Matrix< T, Rows1, Match, Order1, eMatrixLayout::ROW_MAJOR, Packed > &lhs, const Matrix< U, Match, Columns2, Order2, eMatrixLayout::ROW_MAJOR, Packed > &rhs) -> Matrix< V, Rows1, Columns2, Order1, eMatrixLayout::ROW_MAJOR, Packed >
Definition: MatrixArithmetic.hpp:78
Represents a vector in N-dimensional space.
Definition: Definitions.hpp:57
Enables element swizzling (reordering elements) for vectors.
Definition: Definitions.hpp:60
Definition: Approx.hpp:11
Matrix< T, Rows, Columns, Order, Layout, Packed > operator/(T s, const Matrix< T, Rows, Columns, Order, Layout, Packed > &mat)
Definition: MatrixArithmetic.hpp:333
Matrix< U, Rows, Columns, Order1, Layout1, Packed > & operator-=(Matrix< T, Rows, Columns, Order1, Layout1, Packed > &lhs, const Matrix< U, Rows, Columns, Order2, Layout2, Packed > &rhs)
Performs matrix subtraction and stores result in this.
Definition: MatrixArithmetic.hpp:296
Matrix< U, Rows, Columns, Order1, SameLayout, Packed > operator-(const Matrix< T, Rows, Columns, Order1, SameLayout, Packed > &lhs, const Matrix< U, Rows, Columns, Order2, SameLayout, Packed > &rhs)
Definition: MatrixArithmetic.hpp:239
Matrix< T1, Dim, Dim, Order1, Layout1, Packed > & operator*=(Matrix< T1, Dim, Dim, Order1, Layout1, Packed > &lhs, const Matrix< T2, Dim, Dim, Order2, Layout2, Packed > &rhs)
Definition: MatrixArithmetic.hpp:198
Matrix< T, Rows, Columns, Order, Layout, Packed > & operator/=(Matrix< T, Rows, Columns, Order, Layout, Packed > &mat, T s)
Divides all elements of the matrix by scalar.
Definition: MatrixArithmetic.hpp:321
Definition: Traits.hpp:218
Matrix< U, Rows, Columns, Order1, SameLayout, Packed > operator+(const Matrix< T, Rows, Columns, Order1, SameLayout, Packed > &lhs, const Matrix< U, Rows, Columns, Order2, SameLayout, Packed > &rhs)
Definition: MatrixArithmetic.hpp:222