Berserk
TVecN.hpp
Go to the documentation of this file.
1 /**********************************************************************************/
2 /* This file is part of Berserk Engine project */
3 /* https://github.com/EgorOrachyov/Berserk */
4 /**********************************************************************************/
5 /* MIT License */
6 /* */
7 /* Copyright (c) 2018 - 2021 Egor Orachyov */
8 /* */
9 /* Permission is hereby granted, free of charge, to any person obtaining a copy */
10 /* of this software and associated documentation files (the "Software"), to deal */
11 /* in the Software without restriction, including without limitation the rights */
12 /* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell */
13 /* copies of the Software, and to permit persons to whom the Software is */
14 /* furnished to do so, subject to the following conditions: */
15 /* */
16 /* The above copyright notice and this permission notice shall be included in all */
17 /* copies or substantial portions of the Software. */
18 /* */
19 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR */
20 /* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, */
21 /* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE */
22 /* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER */
23 /* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, */
24 /* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */
25 /* SOFTWARE. */
26 /**********************************************************************************/
27 
28 #ifndef BERSERK_TVECN_H
29 #define BERSERK_TVECN_H
30 
31 #include <core/Config.hpp>
32 #include <core/Crc32.hpp>
33 #include <core/Memory.hpp>
34 #include <core/Typedefs.hpp>
35 #include <core/math/MathUtils.hpp>
36 
37 #include <initializer_list>
38 #include <ostream>
39 
41 
54 template<typename T, uint32 N>
55 class TVecN {
56 public:
57  static_assert(N > 0, "Vector size must be more than 0");
58 
59  TVecN() noexcept {
60  Zero();
61  }
62 
63  explicit TVecN(T x) : TVecN() {
64  static_assert(N >= 1, "Out of bounds index assignment");
65  values[0] = x;
66  }
67 
68  TVecN(T x, T y) : TVecN() {
69  static_assert(N >= 2, "Out of bounds index assignment");
70  values[0] = x;
71  values[1] = y;
72  }
73 
74  TVecN(T x, T y, T z) : TVecN() {
75  static_assert(N >= 3, "Out of bounds index assignment");
76  values[0] = x;
77  values[1] = y;
78  values[2] = z;
79  }
80 
81  TVecN(T x, T y, T z, T w) : TVecN() {
82  static_assert(N >= 4, "Out of bounds index assignment");
83  values[0] = x;
84  values[1] = y;
85  values[2] = z;
86  values[3] = w;
87  }
88 
89  template<uint32 M>
90  TVecN(const TVecN<T, M> &v, T a) : TVecN() {
91  static_assert(N >= M + 1, "Out of bounds index assignment");
92  Memory::Copy(&values[0], &v.values[0], sizeof(T) * M);
93  values[M] = a;
94  }
95 
96  TVecN(const std::initializer_list<T> &list) noexcept : TVecN<T, N>() {
97  uint32 i = 0;
98  for (const auto &a : list) {
99 
100  if (i >= N) return;
101 
102  values[i] = a;
103  i += 1;
104  }
105  }
106 
107  TVecN(const TVecN &other) noexcept {
108  for (uint32 i = 0; i < N; i++) {
109  values[i] = other.values[i];
110  }
111  }
112 
113  TVecN(TVecN &&other) noexcept {
114  for (uint32 i = 0; i < N; i++) {
115  values[i] = other.values[i];
116  }
117  }
118 
119  template<uint32 M>
120  explicit TVecN(const TVecN<T, M> &other) noexcept : TVecN<T, N>() {
121  uint32 i = 0;
122  while (i < N && i < M) {
123  values[i] = other.values[i];
124  i += 1;
125  }
126  }
127 
128  TVecN &operator=(const TVecN &other) {
129  if (this != &other)
130  Memory::Copy(&values[0], &other.values[0], N * sizeof(T));
131  return *this;
132  }
133 
134  TVecN &operator=(TVecN &&other) noexcept {
135  if (this != &other)
136  Memory::Copy(&values[0], &other.values[0], N * sizeof(T));
137  return *this;
138  }
139 
140  TVecN operator+(const TVecN &other) const {
141  TVecN<T, N> r;
142 
143  for (uint32 i = 0; i < N; i++) {
144  r.values[i] = values[i] + other.values[i];
145  }
146 
147  return r;
148  }
149 
150  TVecN operator-(const TVecN &other) const {
151  TVecN<T, N> r;
152 
153  for (uint32 i = 0; i < N; i++) {
154  r.values[i] = values[i] - other.values[i];
155  }
156 
157  return r;
158  }
159 
160  TVecN operator*(const TVecN &other) const {
161  TVecN<T, N> r;
162 
163  for (uint32 i = 0; i < N; i++) {
164  r.values[i] = values[i] * other.values[i];
165  }
166 
167  return r;
168  }
169 
170  TVecN operator/(const TVecN &other) const {
171  TVecN<T, N> r;
172 
173  for (uint32 i = 0; i < N; i++) {
174  r.values[i] = values[i] / other.values[i];
175  }
176 
177  return r;
178  }
179 
180  TVecN operator+(T a) const {
181  TVecN<T, N> r;
182 
183  for (uint32 i = 0; i < N; i++) {
184  r.values[i] = values[i] + a;
185  }
186 
187  return r;
188  }
189 
190  TVecN operator-(T a) const {
191  TVecN<T, N> r;
192 
193  for (uint32 i = 0; i < N; i++) {
194  r.values[i] = values[i] - a;
195  }
196 
197  return r;
198  }
199 
200  TVecN operator*(T a) const {
201  TVecN<T, N> r;
202 
203  for (uint32 i = 0; i < N; i++) {
204  r.values[i] = values[i] * a;
205  }
206 
207  return r;
208  }
209 
210  TVecN operator/(T a) const {
211  TVecN<T, N> r;
212 
213  for (uint32 i = 0; i < N; i++) {
214  r.values[i] = values[i] / a;
215  }
216 
217  return r;
218  }
219 
220  TVecN &operator+=(const TVecN &other) {
221  for (uint32 i = 0; i < N; i++) {
222  values[i] += other.values[i];
223  }
224 
225  return *this;
226  }
227 
228  TVecN &operator-=(const TVecN &other) {
229  for (uint32 i = 0; i < N; i++) {
230  values[i] -= other.values[i];
231  }
232 
233  return *this;
234  }
235 
236  TVecN &operator*=(const TVecN &other) {
237  for (uint32 i = 0; i < N; i++) {
238  values[i] *= other.values[i];
239  }
240 
241  return *this;
242  }
243 
244  TVecN &operator/=(const TVecN &other) {
245  for (uint32 i = 0; i < N; i++) {
246  values[i] /= other.values[i];
247  }
248 
249  return *this;
250  }
251 
253  for (uint32 i = 0; i < N; i++) {
254  values[i] += a;
255  }
256 
257  return *this;
258  }
259 
261  for (uint32 i = 0; i < N; i++) {
262  values[i] -= a;
263  }
264 
265  return *this;
266  }
267 
269  for (uint32 i = 0; i < N; i++) {
270  values[i] *= a;
271  }
272 
273  return *this;
274  }
275 
277  for (uint32 i = 0; i < N; i++) {
278  values[i] /= a;
279  }
280 
281  return *this;
282  }
283 
284  TVecN operator-() const {
285  return *this * (-1);
286  }
287 
288  bool operator<=(const TVecN &other) const {
289  bool done = true;
290 
291  for (uint32 i = 0; i < N; i++) {
292  done = done && (values[i] <= other.values[i]);
293  }
294  return done;
295  }
296 
297  bool operator>=(const TVecN &other) const {
298  bool done = true;
299 
300  for (uint32 i = 0; i < N; i++) {
301  done = done && (values[i] >= other.values[i]);
302  }
303  return done;
304  }
305 
306  bool operator<(const TVecN &other) const {
307  bool done = true;
308 
309  for (uint32 i = 0; i < N; i++) {
310  done = done && (values[i] < other.values[i]);
311  }
312  return done;
313  }
314 
315  bool operator>(const TVecN &other) const {
316  bool done = true;
317 
318  for (uint32 i = 0; i < N; i++) {
319  done = done && (values[i] > other.values[i]);
320  }
321  return done;
322  }
323 
324  bool operator==(const TVecN &other) const {
325  bool r = true;
326 
327  for (uint32 i = 0; i < N; i++) {
328  r = r && (values[i] == other.values[i]);
329  }
330 
331  return r;
332  }
333 
334  bool operator!=(const TVecN &other) const {
335  bool r = false;
336 
337  for (uint32 i = 0; i < N; i++) {
338  r = r || (values[i] != other.values[i]);
339  }
340 
341  return r;
342  }
343 
344  static T Distance2(const TVecN &a, const TVecN &b) {
345  auto c = a - b;
346  return c.Length2();
347  }
348 
349  static T Distance(const TVecN &a, const TVecN &b) {
350  auto c = a - b;
351  return c.Length();
352  }
353 
354  static T Dot(const TVecN &a, const TVecN &b) {
355  T r = 0;
356 
357  for (uint32 i = 0; i < N; i++) {
358  r += a.values[i] * b.values[i];
359  }
360 
361  return r;
362  }
363 
364  static T Angle(const TVecN &a, const TVecN &b) {
365  return MathUtils::Acos(Dot(a.Normalized(), b.Normalized()));
366  }
367 
375  static TVecN Cross(const TVecN &a, const TVecN &b) {
376  static_assert(N == 3, "Cross product only defined for 3-dim vectors");
377 
378  TVecN<T, 3> result;
379 
380  // a x b = det | i j k |
381  // | x1 y1 z1 |
382  // | x2 y2 z2 |
383 
384  result[0] = a.y() * b.z() - a.z() * b.y();
385  result[1] = a.z() * b.x() - a.x() * b.z();
386  result[2] = a.x() * b.y() - a.y() * b.x();
387 
388  return result;
389  }
390 
399  static T Triple(const TVecN &a, const TVecN &b, const TVecN &c) {
400  static_assert(N == 3, "Triple product only defined for 3-dim vectors");
401 
402  // a b c - tight three
403  // a x b - area of figure
404  // dot(a x b, c) - volume of the figure
405 
406  return Dot(Cross(a, b), c);
407  }
408 
409  static TVecN Lerp(float t, const TVecN &a, const TVecN &b) {
410  TVecN r;
411 
412  for (uint32 i = 0; i < N; i++) {
413  r.values[i] = MathUtils::Lerp(t, a.values[i], b.values[i]);
414  }
415 
416  return r;
417  }
418 
419  static TVecN Slerp(T t, const TVecN &a, const TVecN &b) {
420  T ang = Angle(a, b);
421 
422  if (ang <= MathUtils::THRESH_FLOAT32) {
423  return Lerp(t, a, b);
424  }
425 
426  TVecN<T, N> r;
427  T angleSin = MathUtils::Sin(ang);
428  T angle1 = MathUtils::Sin(ang * (1 - t)) / angleSin;
429  T angle2 = MathUtils::Sin(ang * t) / angleSin;
430 
431  for (uint32 i = 0; i < N; i++) {
432  r.values[i] = a.values[i] * angle1 + b.values[i] * angle2;
433  }
434 
435  return r;
436  }
437 
438  static TVecN Slerp(T t, T ang, const TVecN &a, const TVecN &b) {
439  if (ang <= MathUtils::THRESH_FLOAT32) {
440  return Lerp(t, a, b);
441  }
442 
443  TVecN<T, N> r;
444  T angleSin = MathUtils::Sin(ang);
445  T angle1 = MathUtils::Sin(ang * (1 - t)) / angleSin;
446  T angle2 = MathUtils::Sin(ang * t) / angleSin;
447 
448  for (uint32 i = 0; i < N; i++) {
449  r.values[i] = a.values[i] * angle1 + b.values[i] * angle2;
450  }
451 
452  return r;
453  }
454 
455  static TVecN Min(const TVecN &a, const TVecN &b) {
456  TVecN<T, N> r;
457 
458  for (uint32 i = 0; i < N; i++) {
459  r.values[i] = MathUtils::Min(a.values[i], b.values[i]);
460  }
461 
462  return r;
463  }
464 
465  static TVecN Max(const TVecN &a, const TVecN &b) {
466  TVecN<T, N> r;
467 
468  for (uint32 i = 0; i < N; i++) {
469  r.values[i] = MathUtils::Max(a.values[i], b.values[i]);
470  }
471 
472  return r;
473  }
474 
475  static TVecN Clamp(const TVecN &t, const TVecN &left, const TVecN &right) {
476  TVecN<T, N> r;
477 
478  for (uint32 i = 0; i < N; i++) {
479  r.values[i] = MathUtils::Clamp(t.values[i], left.values[i], right.values[i]);
480  }
481 
482  return r;
483  }
484 
485  TVecN Abs() const {
486  TVecN<T, N> r;
487 
488  for (uint32 i = 0; i < N; i++) {
489  r.values[i] = MathUtils::Abs(values[i]);
490  }
491 
492  return r;
493  }
494 
495  TVecN Pow(T factor) const {
496  TVecN<T, N> r;
497 
498  for (uint32 i = 0; i < N; i++) {
499  r.values[i] = MathUtils::Pow(values[i], factor);
500  }
501 
502  return r;
503  }
504 
505  T Length2() const {
506  T r = 0;
507 
508  for (uint32 i = 0; i < N; i++) {
509  r += values[i] * values[i];
510  }
511 
512  return r;
513  }
514 
515  T Length() const {
516  T l2 = Length2();
517  return MathUtils::Sqrt(l2);
518  }
519 
520  TVecN Normalized() const {
521  TVecN r = *this;
522  return r.NormalizeThis();
523  }
524 
526  T len2 = Length2();
527 
529  Zero();
530  } else {
531  T len = MathUtils::Sqrt(len2);
532  *this /= len;
533  }
534 
535  return *this;
536  }
537 
538  TVecN &Zero() {
539  for (auto &a : values) {
540  a = 0;
541  }
542 
543  return *this;
544  }
545 
546  Crc32Hash Hash() const {
547  Crc32Builder builder;
548 
549  for (const auto &v : values) {
550  builder.Hash(&v, sizeof(T));
551  }
552 
553  return builder.GetHash();
554  }
555 
556  T x() const {
557  static_assert(N >= 1, "No component");
558  return values[0];
559  }
560 
561  T y() const {
562  static_assert(N >= 2, "No component");
563  return values[1];
564  }
565 
566  T z() const {
567  static_assert(N >= 3, "No component");
568  return values[2];
569  }
570 
571  T w() const {
572  static_assert(N >= 4, "No component");
573  return values[3];
574  }
575 
576  T &operator[](uint32 index) { return values[index]; }
577  const T &operator[](uint32 index) const { return values[index]; }
578 
579  T *GetData() { return values; }
580  const T *GetData() const { return values; }
581 
582  static TVecN AxisX() {
583  return TVecN<T, N>(1);
584  }
585 
586  static TVecN AxisY() {
587  return TVecN<T, N>(0, 1);
588  }
589 
590  static TVecN AxisZ() {
591  return TVecN<T, N>(0, 0, 1);
592  }
593 
594 public:
596 };
597 
601 
605 
609 
613 
621 
627 
628 namespace std {
629 
630  template<typename T, BRK_NS::uint32 N>
631  struct hash<BRK_NS::TVecN<T, N>> {
632  public:
633  std::size_t operator()(const BRK_NS::TVecN<T, N> &vec) const {
634  return vec.Hash();
635  }
636  };
637 
638 }// namespace std
639 
640 template<typename T, BRK_NS::uint32 N>
641 inline std::ostream &operator<<(std::ostream &ostream, const BRK_NS::TVecN<T, N> &vec) {
642  ostream << "(";
643  ostream << vec[0];
644  for (BRK_NS::uint32 i = 1; i < N; i++) {
645  ostream << "," << vec[i];
646  }
647  ostream << ")";
648  return ostream;
649 }
650 
651 #endif//BERSERK_TVECN_H
#define BRK_NS_END
Definition: Config.hpp:48
#define BRK_NS
Definition: Config.hpp:50
std::ostream & operator<<(std::ostream &ostream, const BRK_NS::TVecN< T, N > &vec)
Definition: TVecN.hpp:641
std::size_t size_t
Definition: Typedefs.hpp:49
std::uint32_t uint32
Definition: Typedefs.hpp:44
Crc32 hash builder.
Definition: Crc32.hpp:68
Crc32Hash GetHash() const
Definition: Crc32.hpp:86
Crc32Builder & Hash(const void *buffer, size_t size)
Definition: Crc32.hpp:78
Crc32 hash value type.
static float Lerp(float t, float left, float right)
Definition: MathUtils.hpp:156
static float Min(float a, float b)
Definition: MathUtils.hpp:82
static T Clamp(T t, T left, T right)
Definition: MathUtils.hpp:188
static float Pow(float a, float p)
Definition: MathUtils.hpp:112
static float Sqrt(float a)
Definition: MathUtils.hpp:106
static float Acos(float a)
Definition: MathUtils.hpp:100
static BRK_API const float THRESH_FLOAT32
Definition: MathUtils.hpp:53
static BRK_API const float THRESH_ZERO_NORM_SQUARED
Definition: MathUtils.hpp:56
static float Max(float a, float b)
Definition: MathUtils.hpp:85
static float Abs(float a)
Definition: MathUtils.hpp:124
static float Sin(float a)
Definition: MathUtils.hpp:88
static void Copy(void *destination, const void *source, size_t sizeInBytes)
Definition: Memory.hpp:58
Generic vector class for an N dimensional space base on type T.
Definition: TVecN.hpp:55
TVecN & operator/=(const TVecN &other)
Definition: TVecN.hpp:244
T * GetData()
Definition: TVecN.hpp:579
static TVecN Slerp(T t, const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:419
bool operator>(const TVecN &other) const
Definition: TVecN.hpp:315
T Length2() const
Definition: TVecN.hpp:505
TVecN(const std::initializer_list< T > &list) noexcept
Definition: TVecN.hpp:96
TVecN & operator/=(T a)
Definition: TVecN.hpp:276
static TVecN Min(const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:455
TVecN & Zero()
Definition: TVecN.hpp:538
bool operator>=(const TVecN &other) const
Definition: TVecN.hpp:297
TVecN(const TVecN< T, M > &v, T a)
Definition: TVecN.hpp:90
bool operator!=(const TVecN &other) const
Definition: TVecN.hpp:334
TVecN(T x, T y)
Definition: TVecN.hpp:68
T z() const
Definition: TVecN.hpp:566
const T * GetData() const
Definition: TVecN.hpp:580
static T Distance(const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:349
T x() const
Definition: TVecN.hpp:556
TVecN & operator-=(T a)
Definition: TVecN.hpp:260
static TVecN Slerp(T t, T ang, const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:438
TVecN(T x, T y, T z, T w)
Definition: TVecN.hpp:81
static TVecN Cross(const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:375
const T & operator[](uint32 index) const
Definition: TVecN.hpp:577
T & operator[](uint32 index)
Definition: TVecN.hpp:576
static TVecN Max(const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:465
static TVecN AxisZ()
Definition: TVecN.hpp:590
TVecN operator-() const
Definition: TVecN.hpp:284
TVecN & operator+=(T a)
Definition: TVecN.hpp:252
TVecN(TVecN &&other) noexcept
Definition: TVecN.hpp:113
TVecN(T x, T y, T z)
Definition: TVecN.hpp:74
static TVecN AxisX()
Definition: TVecN.hpp:582
TVecN operator/(T a) const
Definition: TVecN.hpp:210
TVecN operator/(const TVecN &other) const
Definition: TVecN.hpp:170
TVecN(const TVecN< T, M > &other) noexcept
Definition: TVecN.hpp:120
TVecN operator*(T a) const
Definition: TVecN.hpp:200
TVecN & operator=(const TVecN &other)
Definition: TVecN.hpp:128
static TVecN AxisY()
Definition: TVecN.hpp:586
static TVecN Clamp(const TVecN &t, const TVecN &left, const TVecN &right)
Definition: TVecN.hpp:475
TVecN & operator*=(const TVecN &other)
Definition: TVecN.hpp:236
TVecN operator*(const TVecN &other) const
Definition: TVecN.hpp:160
bool operator==(const TVecN &other) const
Definition: TVecN.hpp:324
TVecN Abs() const
Definition: TVecN.hpp:485
TVecN & operator+=(const TVecN &other)
Definition: TVecN.hpp:220
TVecN Normalized() const
Definition: TVecN.hpp:520
TVecN & operator*=(T a)
Definition: TVecN.hpp:268
TVecN operator+(const TVecN &other) const
Definition: TVecN.hpp:140
TVecN & operator=(TVecN &&other) noexcept
Definition: TVecN.hpp:134
T w() const
Definition: TVecN.hpp:571
TVecN operator-(const TVecN &other) const
Definition: TVecN.hpp:150
T y() const
Definition: TVecN.hpp:561
TVecN() noexcept
Definition: TVecN.hpp:59
static T Angle(const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:364
static T Distance2(const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:344
TVecN operator+(T a) const
Definition: TVecN.hpp:180
TVecN(const TVecN &other) noexcept
Definition: TVecN.hpp:107
bool operator<(const TVecN &other) const
Definition: TVecN.hpp:306
TVecN & operator-=(const TVecN &other)
Definition: TVecN.hpp:228
static T Triple(const TVecN &a, const TVecN &b, const TVecN &c)
Definition: TVecN.hpp:399
T values[N]
Definition: TVecN.hpp:595
static T Dot(const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:354
TVecN & NormalizeThis()
Definition: TVecN.hpp:525
TVecN Pow(T factor) const
Definition: TVecN.hpp:495
T Length() const
Definition: TVecN.hpp:515
bool operator<=(const TVecN &other) const
Definition: TVecN.hpp:288
Crc32Hash Hash() const
Definition: TVecN.hpp:546
TVecN operator-(T a) const
Definition: TVecN.hpp:190
TVecN(T x)
Definition: TVecN.hpp:63
static TVecN Lerp(float t, const TVecN &a, const TVecN &b)
Definition: TVecN.hpp:409
Definition: GLDevice.cpp:46
Definition: TQuat.hpp:431
std::size_t operator()(const BRK_NS::TVecN< T, N > &vec) const
Definition: TVecN.hpp:633