Leonetienne/Eule
Homemade math library, mainly targetted towards computer graphics
Vector3.cpp
Go to the documentation of this file.
1 #include "Vector3.h"
2 #include "Math.h"
3 #include <iostream>
4 
5 //#define _EULE_NO_INTRINSICS_
6 #ifndef _EULE_NO_INTRINSICS_
7 #include <immintrin.h>
8 #endif
9 
10 using namespace Eule;
11 
12 /*
13  NOTE:
14  Here you will find bad, unoptimized methods for T=int.
15  This is because the compiler needs a method for each type in each instantiation of the template!
16  I can't generalize the methods when heavily optimizing for doubles.
17  These functions will get called VERY rarely, if ever at all, for T=int, so it's ok.
18  The T=int instantiation only exists to store a value-pair of two ints. Not so-much as a vector in terms of vector calculus.
19 */
20 
21 // Good, optimized chad version for doubles
22 double Vector3<double>::DotProduct(const Vector3<double>& other) const
23 {
24  #ifndef _EULE_NO_INTRINSICS_
25 
26  // Move vector components into registers
27  __m256 __vector_self = _mm256_set_ps(0,0,0,0,0, (float)z, (float)y, (float)x);
28  __m256 __vector_other = _mm256_set_ps(0,0,0,0,0, (float)other.z, (float)other.y, (float)other.x);
29 
30  // Define bitmask, and execute computation
31  const int mask = 0x71; // -> 0111 1000 -> use positions 0111 (last 3) of the vectors supplied, and place them in 1000 (first only) element of __dot
32  __m256 __dot = _mm256_dp_ps(__vector_self, __vector_other, mask);
33 
34  // Retrieve result, and return it
35  float result[8];
36  _mm256_storeu_ps(result, __dot);
37 
38  return result[0];
39 
40  #else
41  return (x * other.x) +
42  (y * other.y) +
43  (z * other.z);
44  #endif
45 }
46 
47 // Slow, lame version for intcels
48 double Vector3<int>::DotProduct(const Vector3<int>& other) const
49 {
50  int iDot = (x * other.x) + (y * other.y) + (z * other.z);
51  return (double)iDot;
52 }
53 
54 
55 
56 // Good, optimized chad version for doubles
58 {
59  Vector3<double> cp;
60  cp.x = (y * other.z) - (z * other.y);
61  cp.y = (z * other.x) - (x * other.z);
62  cp.z = (x * other.y) - (y * other.x);
63 
64  return cp;
65 }
66 
67 // Slow, lame version for intcels
69 {
70  Vector3<double> cp;
71  cp.x = ((double)y * (double)other.z) - ((double)z * (double)other.y);
72  cp.y = ((double)z * (double)other.x) - ((double)x * (double)other.z);
73  cp.z = ((double)x * (double)other.y) - ((double)y * (double)other.x);
74 
75  return cp;
76 }
77 
78 
79 
80 // Good, optimized chad version for doubles
81 double Vector3<double>::SqrMagnitude() const
82 {
83  // x.DotProduct(x) == x.SqrMagnitude()
84  return DotProduct(*this);
85 }
86 
87 // Slow, lame version for intcels
89 {
90  int iSqrMag = x*x + y*y + z*z;
91  return (double)iSqrMag;
92 }
93 
94 template <typename T>
95 double Vector3<T>::Magnitude() const
96 {
97  return sqrt(SqrMagnitude());
98 }
99 
100 
101 
103 {
104  #ifndef _EULE_NO_INTRINSICS_
105 
106  // Load vectors into registers
107  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
108  __m256d __vector_scalar = _mm256_set_pd(0, scalar.z, scalar.y, scalar.x);
109 
110  // Multiply them
111  __m256d __product = _mm256_mul_pd(__vector_self, __vector_scalar);
112 
113  // Retrieve result
114  double result[4];
115  _mm256_storeu_pd(result, __product);
116 
117  // Return value
118  return Vector3<double>(
119  result[0],
120  result[1],
121  result[2]
122  );
123 
124  #else
125 
126  return Vector3<double>(
127  x * scalar.x,
128  y * scalar.y,
129  z * scalar.z
130  );
131 
132  #endif
133 }
134 
136 {
137  return Vector3<int>(
138  x * scalar.x,
139  y * scalar.y,
140  z * scalar.z
141  );
142 }
143 
144 
145 
146 template<typename T>
148 {
149  Vector3<double> norm(x, y, z);
150  norm.NormalizeSelf();
151 
152  return norm;
153 }
154 
155 // Method to normalize a Vector3d
157 {
158  const double length = Magnitude();
159 
160  // Prevent division by 0
161  if (length == 0)
162  {
163  x = 0;
164  y = 0;
165  z = 0;
166  }
167  else
168  {
169  #ifndef _EULE_NO_INTRINSICS_
170 
171  // Load vector and length into registers
172  __m256d __vec = _mm256_set_pd(0, z, y, x);
173  __m256d __len = _mm256_set1_pd(length);
174 
175  // Divide
176  __m256d __prod = _mm256_div_pd(__vec, __len);
177 
178  // Extract and set values
179  double prod[4];
180  _mm256_storeu_pd(prod, __prod);
181 
182  x = prod[0];
183  y = prod[1];
184  z = prod[2];
185 
186  #else
187 
188  x /= length;
189  y /= length;
190  z /= length;
191 
192  #endif
193  }
194 
195  return;
196 }
197 
198 // You can't normalize an int vector, ffs!
199 // But we need an implementation for T=int
201 {
202  std::cerr << "Stop normalizing int-vectors!!" << std::endl;
203  x = 0;
204  y = 0;
205  z = 0;
206 
207  return;
208 }
209 
210 
211 
212 template<typename T>
213 bool Vector3<T>::Similar(const Vector3<T>& other, double epsilon) const
214 {
215  return
216  (::Math::Similar(x, other.x, epsilon)) &&
217  (::Math::Similar(y, other.y, epsilon)) &&
218  (::Math::Similar(z, other.z, epsilon))
219  ;
220 }
221 
222 template<typename T>
224 {
225  return Vector3<int>((int)x, (int)y, (int)z);
226 }
227 
228 template<typename T>
230 {
231  return Vector3<double>((double)x, (double)y, (double)z);
232 }
233 
234 template<typename T>
235 T& Vector3<T>::operator[](std::size_t idx)
236 {
237  switch (idx)
238  {
239  case 0:
240  return x;
241  case 1:
242  return y;
243  case 2:
244  return z;
245  default:
246  throw std::out_of_range("Array descriptor on Vector3<T> out of range!");
247  }
248 }
249 
250 template<typename T>
251 const T& Vector3<T>::operator[](std::size_t idx) const
252 {
253  switch (idx)
254  {
255  case 0:
256  return x;
257  case 1:
258  return y;
259  case 2:
260  return z;
261  default:
262  throw std::out_of_range("Array descriptor on Vector3<T> out of range!");
263  }
264 }
265 
266 
267 
268 // Good, optimized chad version for doubles
269 void Vector3<double>::LerpSelf(const Vector3<double>& other, double t)
270 {
271  const double it = 1.0 - t; // Inverse t
272 
273  #ifndef _EULE_NO_INTRINSICS_
274 
275  // Move vector components and factors into registers
276  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
277  __m256d __vector_other = _mm256_set_pd(0, other.z, other.y, other.x);
278  __m256d __t = _mm256_set1_pd(t);
279  __m256d __it = _mm256_set1_pd(it); // Inverse t
280 
281  // Procedure:
282  // (__vector_self * __it) + (__vector_other * __t)
283 
284  __m256d __sum = _mm256_set1_pd(0); // this will hold the sum of the two multiplications
285 
286  __sum = _mm256_fmadd_pd(__vector_self, __it, __sum);
287  __sum = _mm256_fmadd_pd(__vector_other, __t, __sum);
288 
289  // Retrieve result, and apply it
290  double sum[4];
291  _mm256_storeu_pd(sum, __sum);
292 
293  x = sum[0];
294  y = sum[1];
295  z = sum[2];
296 
297  #else
298 
299  x = it*x + t*other.x;
300  y = it*y + t*other.y;
301  z = it*z + t*other.z;
302 
303  #endif
304 
305  return;
306 }
307 
308 
309 
310 // Slow, lame version for intcels
311 void Vector3<int>::LerpSelf(const Vector3<int>& other, double t)
312 {
313  const double it = 1.0 - t; // Inverse t
314 
315  x = (int)(it * (double)x + t * (double)other.x);
316  y = (int)(it * (double)y + t * (double)other.y);
317  z = (int)(it * (double)z + t * (double)other.z);
318 
319  return;
320 }
321 
322 Vector3<double> Vector3<double>::Lerp(const Vector3<double>& other, double t) const
323 {
324  Vector3d copy(*this);
325  copy.LerpSelf(other, t);
326 
327  return copy;
328 }
329 
330 Vector3<double> Vector3<int>::Lerp(const Vector3<int>& other, double t) const
331 {
332  Vector3d copy(this->ToDouble());
333  copy.LerpSelf(other.ToDouble(), t);
334 
335  return copy;
336 }
337 
338 
339 
341 {
342  #ifndef _EULE_NO_INTRINSICS_
343 
344  // Move vector components and factors into registers
345  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
346  __m256d __vector_other = _mm256_set_pd(0, other.z, other.y, other.x);
347 
348  // Add the components
349  __m256d __sum = _mm256_add_pd(__vector_self, __vector_other);
350 
351  // Retrieve and return these values
352  double sum[4];
353  _mm256_storeu_pd(sum, __sum);
354 
355  return Vector3<double>(
356  sum[0],
357  sum[1],
358  sum[2]
359  );
360 
361  #else
362 
363  return Vector3<double>(
364  x + other.x,
365  y + other.y,
366  z + other.z
367  );
368  #endif
369 }
370 
371 template<typename T>
373 {
374  return Vector3<T>(
375  x + other.x,
376  y + other.y,
377  z + other.z
378  );
379 }
380 
381 
382 
384 {
385  #ifndef _EULE_NO_INTRINSICS_
386 
387  // Move vector components and factors into registers
388  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
389  __m256d __vector_other = _mm256_set_pd(0, other.z, other.y, other.x);
390 
391  // Add the components
392  __m256d __sum = _mm256_add_pd(__vector_self, __vector_other);
393 
394  // Retrieve and apply these values
395  double sum[4];
396  _mm256_storeu_pd(sum, __sum);
397 
398  x = sum[0];
399  y = sum[1];
400  z = sum[2];
401 
402  #else
403 
404  x += other.x;
405  y += other.y;
406  z += other.z;
407 
408  #endif
409 
410  return;
411 }
412 
413 template<typename T>
415 {
416  x += other.x;
417  y += other.y;
418  z += other.z;
419  return;
420 }
421 
422 
423 
425 {
426  #ifndef _EULE_NO_INTRINSICS_
427 
428  // Move vector components and factors into registers
429  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
430  __m256d __vector_other = _mm256_set_pd(0, other.z, other.y, other.x);
431 
432  // Subtract the components
433  __m256d __diff = _mm256_sub_pd(__vector_self, __vector_other);
434 
435  // Retrieve and return these values
436  double diff[4];
437  _mm256_storeu_pd(diff, __diff);
438 
439  return Vector3<double>(
440  diff[0],
441  diff[1],
442  diff[2]
443  );
444 
445  #else
446 
447  return Vector3<double>(
448  x - other.x,
449  y - other.y,
450  z - other.z
451  );
452  #endif
453 }
454 
455 template<typename T>
457 {
458  return Vector3<T>(
459  x - other.x,
460  y - other.y,
461  z - other.z
462  );
463 }
464 
465 
466 
468 {
469  #ifndef _EULE_NO_INTRINSICS_
470 
471  // Move vector components and factors into registers
472  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
473  __m256d __vector_other = _mm256_set_pd(0, other.z, other.y, other.x);
474 
475  // Subtract the components
476  __m256d __diff = _mm256_sub_pd(__vector_self, __vector_other);
477 
478  // Retrieve and apply these values
479  double diff[4];
480  _mm256_storeu_pd(diff, __diff);
481 
482  x = diff[0];
483  y = diff[1];
484  z = diff[2];
485 
486  #else
487 
488  x -= other.x;
489  y -= other.y;
490  z -= other.z;
491 
492  #endif
493 
494  return;
495 }
496 
497 template<typename T>
499 {
500  x -= other.x;
501  y -= other.y;
502  z -= other.z;
503  return;
504 }
505 
506 
507 
508 Vector3<double> Vector3<double>::operator*(const double scale) const
509 {
510  #ifndef _EULE_NO_INTRINSICS_
511 
512  // Move vector components and factors into registers
513  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
514  __m256d __scalar = _mm256_set1_pd(scale);
515 
516  // Multiply the components
517  __m256d __prod = _mm256_mul_pd(__vector_self, __scalar);
518 
519  // Retrieve and return these values
520  double prod[4];
521  _mm256_storeu_pd(prod, __prod);
522 
523  return Vector3<double>(
524  prod[0],
525  prod[1],
526  prod[2]
527  );
528 
529  #else
530 
531  return Vector3<double>(
532  x * scale,
533  y * scale,
534  z * scale
535  );
536 
537  #endif
538 }
539 
540 template<typename T>
541 Vector3<T> Vector3<T>::operator*(const T scale) const
542 {
543  return Vector3<T>(
544  x * scale,
545  y * scale,
546  z * scale
547  );
548 }
549 
550 
551 
552 void Vector3<double>::operator*=(const double scale)
553 {
554  #ifndef _EULE_NO_INTRINSICS_
555 
556  // Move vector components and factors into registers
557  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
558  __m256d __scalar = _mm256_set1_pd(scale);
559 
560  // Multiply the components
561  __m256d __prod = _mm256_mul_pd(__vector_self, __scalar);
562 
563  // Retrieve and apply these values
564  double prod[4];
565  _mm256_storeu_pd(prod, __prod);
566 
567  x = prod[0];
568  y = prod[1];
569  z = prod[2];
570 
571  #else
572 
573  x *= scale;
574  y *= scale;
575  z *= scale;
576 
577  #endif
578 
579  return;
580 }
581 
582 template<typename T>
583 void Vector3<T>::operator*=(const T scale)
584 {
585  x *= scale;
586  y *= scale;
587  z *= scale;
588  return;
589 }
590 
591 
592 
593 Vector3<double> Vector3<double>::operator/(const double scale) const
594 {
595  #ifndef _EULE_NO_INTRINSICS_
596 
597  // Move vector components and factors into registers
598  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
599  __m256d __scalar = _mm256_set1_pd(scale);
600 
601  // Divide the components
602  __m256d __prod = _mm256_div_pd(__vector_self, __scalar);
603 
604  // Retrieve and return these values
605  double prod[4];
606  _mm256_storeu_pd(prod, __prod);
607 
608  return Vector3<double>(
609  prod[0],
610  prod[1],
611  prod[2]
612  );
613 
614  #else
615 
616  return Vector3<double>(
617  x / scale,
618  y / scale,
619  z / scale
620  );
621 
622  #endif
623 }
624 
625 template<typename T>
626 Vector3<T> Vector3<T>::operator/(const T scale) const
627 {
628  return Vector3<T>(
629  x / scale,
630  y / scale,
631  z / scale
632  );
633 }
634 
635 
636 
637 void Vector3<double>::operator/=(const double scale)
638 {
639  #ifndef _EULE_NO_INTRINSICS_
640 
641  // Move vector components and factors into registers
642  __m256d __vector_self = _mm256_set_pd(0, z, y, x);
643  __m256d __scalar = _mm256_set1_pd(scale);
644 
645  // Divide the components
646  __m256d __prod = _mm256_div_pd(__vector_self, __scalar);
647 
648  // Retrieve and apply these values
649  double prod[4];
650  _mm256_storeu_pd(prod, __prod);
651 
652  x = prod[0];
653  y = prod[1];
654  z = prod[2];
655 
656  #else
657 
658  x /= scale;
659  y /= scale;
660  z /= scale;
661 
662  #endif
663  return;
664 }
665 
666 template<typename T>
667 void Vector3<T>::operator/=(const T scale)
668 {
669  x /= scale;
670  y /= scale;
671  z /= scale;
672  return;
673 }
674 
675 
676 
677 // Good, optimized chad version for doubles
679 {
680  Vector3<double> newVec;
681 
682  #ifndef _EULE_NO_INTRINSICS_
683  // Store x, y, and z values
684  __m256d __vecx = _mm256_set1_pd(x);
685  __m256d __vecy = _mm256_set1_pd(y);
686  __m256d __vecz = _mm256_set1_pd(z);
687 
688  // Store matrix values
689  __m256d __mat_row0 = _mm256_set_pd(mat[0][0], mat[1][0], mat[2][0], 0);
690  __m256d __mat_row1 = _mm256_set_pd(mat[0][1], mat[1][1], mat[2][1], 0);
691  __m256d __mat_row2 = _mm256_set_pd(mat[0][2], mat[1][2], mat[2][2], 0);
692 
693  // Multiply x, y, z and matrix values
694  __m256d __mul_vecx_row0 = _mm256_mul_pd(__vecx, __mat_row0);
695  __m256d __mul_vecy_row1 = _mm256_mul_pd(__vecy, __mat_row1);
696  __m256d __mul_vecz_row2 = _mm256_mul_pd(__vecz, __mat_row2);
697 
698  // Sum up the products
699  __m256d __sum = _mm256_add_pd(__mul_vecx_row0, _mm256_add_pd(__mul_vecy_row1, __mul_vecz_row2));
700 
701  // Store translation values
702  __m256d __translation = _mm256_set_pd(mat[0][3], mat[1][3], mat[2][3], 0);
703 
704  // Add the translation values
705  __m256d __final = _mm256_add_pd(__sum, __translation);
706 
707  double dfinal[4];
708 
709  _mm256_storeu_pd(dfinal, __final);
710 
711  newVec.x = dfinal[3];
712  newVec.y = dfinal[2];
713  newVec.z = dfinal[1];
714 
715  #else
716  // Rotation, Scaling
717  newVec.x = (mat[0][0] * x) + (mat[1][0] * y) + (mat[2][0] * z);
718  newVec.y = (mat[0][1] * x) + (mat[1][1] * y) + (mat[2][1] * z);
719  newVec.z = (mat[0][2] * x) + (mat[1][2] * y) + (mat[2][2] * z);
720 
721  // Translation
722  newVec.x += mat[0][3];
723  newVec.y += mat[1][3];
724  newVec.z += mat[2][3];
725  #endif
726 
727  return newVec;
728 }
729 
730 // Slow, lame version for intcels
732 {
733  Vector3<double> newVec;
734 
735  // Rotation, Scaling
736  newVec.x = ((mat[0][0] * x) + (mat[1][0] * y) + (mat[2][0] * z));
737  newVec.y = ((mat[0][1] * x) + (mat[1][1] * y) + (mat[2][1] * z));
738  newVec.z = ((mat[0][2] * x) + (mat[1][2] * y) + (mat[2][2] * z));
739 
740  // Translation
741  newVec.x += mat[0][3];
742  newVec.y += mat[1][3];
743  newVec.z += mat[2][3];
744 
745  return Vector3<int>(
746  (int)newVec.x,
747  (int)newVec.y,
748  (int)newVec.z
749  );
750 }
751 
752 
753 
754 // Good, optimized chad version for doubles
755 void Vector3<double>::operator*=(const Matrix4x4& mat)
756 {
757  #ifndef _EULE_NO_INTRINSICS_
758  // Store x, y, and z values
759  __m256d __vecx = _mm256_set1_pd(x);
760  __m256d __vecy = _mm256_set1_pd(y);
761  __m256d __vecz = _mm256_set1_pd(z);
762 
763  // Store matrix values
764  __m256d __mat_row0 = _mm256_set_pd(mat[0][0], mat[1][0], mat[2][0], 0);
765  __m256d __mat_row1 = _mm256_set_pd(mat[0][1], mat[1][1], mat[2][1], 0);
766  __m256d __mat_row2 = _mm256_set_pd(mat[0][2], mat[1][2], mat[2][2], 0);
767 
768  // Multiply x, y, z and matrix values
769  __m256d __mul_vecx_row0 = _mm256_mul_pd(__vecx, __mat_row0);
770  __m256d __mul_vecy_row1 = _mm256_mul_pd(__vecy, __mat_row1);
771  __m256d __mul_vecz_row2 = _mm256_mul_pd(__vecz, __mat_row2);
772 
773  // Sum up the products
774  __m256d __sum = _mm256_add_pd(__mul_vecx_row0, _mm256_add_pd(__mul_vecy_row1, __mul_vecz_row2));
775 
776  // Store translation values
777  __m256d __translation = _mm256_set_pd(mat[0][3], mat[1][3], mat[2][3], 0);
778 
779  // Add the translation values
780  __m256d __final = _mm256_add_pd(__sum, __translation);
781 
782  double dfinal[4];
783 
784  _mm256_storeu_pd(dfinal, __final);
785 
786  x = dfinal[3];
787  y = dfinal[2];
788  z = dfinal[1];
789 
790  #else
791  Vector3<double> buffer = *this;
792  x = (mat[0][0] * buffer.x) + (mat[0][1] * buffer.y) + (mat[0][2] * buffer.z);
793  y = (mat[1][0] * buffer.x) + (mat[1][1] * buffer.y) + (mat[1][2] * buffer.z);
794  z = (mat[2][0] * buffer.x) + (mat[2][1] * buffer.y) + (mat[2][2] * buffer.z);
795 
796  // Translation
797  x += mat[0][3];
798  y += mat[1][3];
799  z += mat[2][3];
800  #endif
801 
802  return;
803 }
804 
805 template<typename T>
807 {
808  return Vector3<T>(
809  -x,
810  -y,
811  -z
812  );
813 }
814 
815 template<typename T>
817 {
818  x = other.x;
819  y = other.y;
820  z = other.z;
821 
822  return;
823 }
824 
825 template<typename T>
826 void Vector3<T>::operator=(Vector3<T>&& other) noexcept
827 {
828  x = std::move(other.x);
829  y = std::move(other.y);
830  z = std::move(other.z);
831 
832  return;
833 }
834 
835 // Slow, lame version for intcels
837 {
838  Vector3<double> buffer(x, y, z);
839 
840  x = (int)((mat[0][0] * buffer.x) + (mat[0][1] * buffer.y) + (mat[0][2] * buffer.z));
841  y = (int)((mat[1][0] * buffer.x) + (mat[1][1] * buffer.y) + (mat[1][2] * buffer.z));
842  z = (int)((mat[2][0] * buffer.x) + (mat[2][1] * buffer.y) + (mat[2][2] * buffer.z));
843 
844  // Translation
845  x += (int)mat[0][3];
846  y += (int)mat[1][3];
847  z += (int)mat[2][3];
848 
849  return;
850 }
851 
852 
853 
854 template<typename T>
855 bool Vector3<T>::operator==(const Vector3<T>& other) const
856 {
857  return
858  (x == other.x) &&
859  (y == other.y) &&
860  (z == other.z);
861 }
862 
863 template<typename T>
864 bool Vector3<T>::operator!=(const Vector3<T>& other) const
865 {
866  return !operator==(other);
867 }
868 
869 
870 #include "Vector2.h"
871 #include "Vector4.h"
872 template<typename T>
874 {
875  return Vector2<T>(x, y);
876 }
877 
878 template<typename T>
880 {
881  return Vector4<T>(x, y, z, 0);
882 }
883 
884 template class Vector3<int>;
885 template class Vector3<double>;
886 
887 // Some handy predefines
888 template <typename T>
889 const Vector3<double> Vector3<T>::up(0, 1, 0);
890 template <typename T>
891 const Vector3<double> Vector3<T>::down(0, -1, 0);
892 template <typename T>
893 const Vector3<double> Vector3<T>::right(1, 0, 0);
894 template <typename T>
895 const Vector3<double> Vector3<T>::left(-1, 0, 0);
896 template <typename T>
897 const Vector3<double> Vector3<T>::forward(0, 0, 1);
898 template <typename T>
899 const Vector3<double> Vector3<T>::backward(0, 0, -1);
900 template <typename T>
901 const Vector3<double> Vector3<T>::one(1, 1, 1);
902 template <typename T>
903 const Vector3<double> Vector3<T>::zero(0, 0, 0);
Eule::Vector3::LerpSelf
void LerpSelf(const Vector3< T > &other, double t)
Will lerp itself towards other by t.
Definition: Vector3.cpp:311
Eule::Vector3< double >
Eule::Vector3::ToDouble
Vector3< double > ToDouble() const
Will convert this vector to a Vector3d.
Definition: Vector3.cpp:229
Math.h
Vector2.h
Eule::Vector3::z
T z
Definition: Vector3.h:96
Eule::Matrix4x4
A matrix 4x4 class representing a 3d transformation.
Definition: Matrix4x4.h:36
Eule::Vector3::x
T x
Definition: Vector3.h:94
Vector4.h
Eule::Vector2
Representation of a 2d vector.
Definition: Vector2.h:14
Eule::Vector3::DotProduct
double DotProduct(const Vector3< T > &other) const
Will compute the dot product to another Vector3.
Definition: Vector3.cpp:48
Vector3.h
Eule::Vector3::NormalizeSelf
void NormalizeSelf()
Will normalize this vector.
Definition: Vector3.cpp:200
Eule
Definition: Collider.h:4
Eule::Vector3::y
T y
Definition: Vector3.h:95
Eule::Vector4
Representation of a 4d vector.
Definition: Vector2.h:8