Diligent Engine API Reference: D:/GitHub/DiligentEngine/DiligentCore/Common/interface/BasicMath.h Source File

Diligent Engine API Reference

BasicMath.h
1 /* Copyright 2015-2018 Egor Yusov
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS.
12 *
13 * In no event and under no legal theory, whether in tort (including negligence),
14 * contract, or otherwise, unless required by applicable law (such as deliberate
15 * and grossly negligent acts) or agreed to in writing, shall any Contributor be
16 * liable for any damages, including any direct, indirect, special, incidental,
17 * or consequential damages of any character arising as a result of this License or
18 * out of the use or inability to use the software (including but not limited to damages
19 * for loss of goodwill, work stoppage, computer failure or malfunction, or any and
20 * all other commercial damages or losses), even if such Contributor has been advised
21 * of the possibility of such damages.
22 */
23
30
31 #pragma once
32
33 #include "DebugUtilities.h"
34
35 #define _USE_MATH_DEFINES
36 #include <math.h>
37
38 #include "HashUtils.h"
39
40 // Common Constants
41
42 #define PI_F 3.1415927f
43
44 // Template Vector & Matrix Classes
45 template <class T> struct Matrix4x4;
46 template <class T> struct Vector4;
47
48 template <class T> struct Vector2
49 {
50 union
51 {
52 struct
53 {
54 T x;
55 T y;
56 };
57 struct
58 {
59 T r;
60 T g;
61 };
62 struct
63 {
64 T u;
65 T v;
66 };
67 };
68
69
70 Vector2 operator-(const Vector2<T> &right)const
71 {
72 return Vector2(x - right.x, y - right.y);
73 }
74
75 Vector2& operator-=(const Vector2<T> &right)
76 {
77 x -= right.x;
78 y -= right.y;
79 return *this;
80 }
81
82 Vector2 operator-()const
83 {
84 return Vector2(-x, -y);
85 }
86
87 Vector2 operator+(const Vector2<T> &right)const
88 {
89 return Vector2(x + right.x, y + right.y);
90 }
91
92 Vector2& operator+=(const Vector2<T> &right)
93 {
94 x += right.x;
95 y += right.y;
96 return *this;
97 }
98
99 Vector2 operator*(T s)const
100 {
101 return Vector2(x * s, y * s);
102 }
103
104 Vector2 operator*(const Vector2 &right)const
105 {
106 return Vector2(x * right.x, y * right.y);
107 }
108
109 Vector2& operator*=( const Vector2 &right)
110 {
111 x *= right.x;
112 y *= right.y;
113 return *this;
114 }
115
116 Vector2& operator*=( T s)
117 {
118 x *= s;
119 y *= s;
120 return *this;
121 }
122
123 Vector2 operator/(const Vector2 &right)const
124 {
125 return Vector2(x / right.x, y / right.y);
126 }
127
128 Vector2& operator/=( const Vector2 &right)
129 {
130 x /= right.x;
131 y /= right.y;
132 return *this;
133 }
134
135 Vector2 operator/(T s)const
136 {
137 return Vector2(x / s, y / s);
138 }
139
140 Vector2& operator/=( T s)
141 {
142 x /= s;
143 y /= s;
144 return *this;
145 }
146
147 bool operator == (const Vector2 &right)const
148 {
149 return x == right.x && y == right.y;
150 }
151
152 bool operator != (const Vector2 &right)const
153 {
154 return !(*this == right);
155 }
156
157 Vector2 operator < ( const Vector2 &right )const
158 {
159 return Vector2(x < right.x ? static_cast<T>(1) : static_cast<T>(0),
160 y < right.y ? static_cast<T>(1) : static_cast<T>(0));
161 }
162
163 Vector2 operator > ( const Vector2 &right )const
164 {
165 return Vector2(x > right.x ? static_cast<T>(1) : static_cast<T>(0),
166 y > right.y ? static_cast<T>(1) : static_cast<T>(0));
167 }
168
169 Vector2 operator <= ( const Vector2 &right )const
170 {
171 return Vector2(x <= right.x ? static_cast<T>(1) : static_cast<T>(0),
172 y <= right.y ? static_cast<T>(1) : static_cast<T>(0));
173 }
174
175 Vector2 operator >= ( const Vector2 &right )const
176 {
177 return Vector2(x >= right.x ? static_cast<T>(1) : static_cast<T>(0),
178 y >= right.y ? static_cast<T>(1) : static_cast<T>(0));
179 }
180
181 T& operator[](size_t index)
182 {
183 return reinterpret_cast<T*>(this)[index];
184 }
185
186 const T& operator[](size_t index)const
187 {
188 return reinterpret_cast<const T*>(this)[index];
189 }
190
191 explicit
192 Vector2(T _x = 0, T _y = 0) : x(_x), y(_y) { }
193 };
194
195 template <class T>
196 Vector2<T> operator*(T s, const Vector2<T> &a)
197 {
198 return a * s;
199 }
200
201
202 template <class T> struct Vector3
203 {
204 union
205 {
206 struct
207 {
208 T x;
209 T y;
210 T z;
211 };
212 struct
213 {
214 T r;
215 T g;
216 T b;
217 };
218 struct
219 {
220 T u;
221 T v;
222 T w;
223 };
224 };
225
226
227 Vector3 operator-( const Vector3 &right )const
228 {
229 return Vector3(x - right.x, y - right.y, z - right.z);
230 }
231
232 Vector3 operator-()const
233 {
234 return Vector3(-x, -y, -z);
235 }
236
237 Vector3& operator-=(const Vector3<T> &right)
238 {
239 x -= right.x;
240 y -= right.y;
241 z -= right.z;
242 return *this;
243 }
244
245 Vector3 operator+( const Vector3 &right )const
246 {
247 return Vector3(x + right.x, y + right.y, z + right.z);
248 }
249
250 Vector3& operator+=(const Vector3<T> &right)
251 {
252 x += right.x;
253 y += right.y;
254 z += right.z;
255 return *this;
256 }
257
258 Vector3 operator*( T s )const
259 {
260 return Vector3(x * s, y * s, z * s);
261 }
262
263 Vector3& operator*=( T s)
264 {
265 x *= s;
266 y *= s;
267 z *= s;
268 return *this;
269 }
270
271 Vector3 operator*( const Vector3 &right )const
272 {
273 return Vector3(x * right.x, y * right.y, z * right.z);
274 }
275
276 Vector3 operator* (const Matrix4x4<T>& m)const
277 {
278 Vector4<T> out4 = Vector4<T>(x, y, z, 1) * m;
279 return Vector3(out4.x / out4.w, out4.y / out4.w, out4.z / out4.w) ;
280 }
281
282 Vector3& operator*=( const Vector3 &right)
283 {
284 x *= right.x;
285 y *= right.y;
286 z *= right.z;
287 return *this;
288 }
289
290 Vector3 operator/ ( T s)const
291 {
292 return Vector3(x / s, y / s, z / s);
293 }
294
295 Vector3& operator/=( T s)
296 {
297 x /= s;
298 y /= s;
299 z /= s;
300 return *this;
301 }
302
303 Vector3 operator/( const Vector3 &right )const
304 {
305 return Vector3(x / right.x, y / right.y, z / right.z);
306 }
307
308 Vector3& operator/=( const Vector3 &right)
309 {
310 x /= right.x;
311 y /= right.y;
312 z /= right.z;
313 return *this;
314 }
315
316 bool operator == (const Vector3 &right)const
317 {
318 return x == right.x && y == right.y && z == right.z;
319 }
320
321 bool operator != (const Vector3 &right)const
322 {
323 return !(*this == right);
324 }
325
326 Vector3 operator < ( const Vector3 &right )const
327 {
328 return Vector3(x < right.x ? static_cast<T>(1) : static_cast<T>(0),
329 y < right.y ? static_cast<T>(1) : static_cast<T>(0),
330 z < right.z ? static_cast<T>(1) : static_cast<T>(0));
331 }
332
333 Vector3 operator > ( const Vector3 &right )const
334 {
335 return Vector3(x > right.x ? static_cast<T>(1) : static_cast<T>(0),
336 y > right.y ? static_cast<T>(1) : static_cast<T>(0),
337 z > right.z ? static_cast<T>(1) : static_cast<T>(0));
338 }
339
340 Vector3 operator <= ( const Vector3 &right )const
341 {
342 return Vector3(x <= right.x ? static_cast<T>(1) : static_cast<T>(0),
343 y <= right.y ? static_cast<T>(1) : static_cast<T>(0),
344 z <= right.z ? static_cast<T>(1) : static_cast<T>(0));
345 }
346
347 Vector3 operator >= ( const Vector3 &right )const
348 {
349 return Vector3(x >= right.x ? static_cast<T>(1) : static_cast<T>(0),
350 y >= right.y ? static_cast<T>(1) : static_cast<T>(0),
351 z >= right.z ? static_cast<T>(1) : static_cast<T>(0));
352 }
353
354 T& operator[](size_t index)
355 {
356 return reinterpret_cast<T*>(this)[index];
357 }
358
359 const T& operator[](size_t index)const
360 {
361 return reinterpret_cast<const T*>(this)[index];
362 }
363
364 explicit
365 Vector3(T _x = 0, T _y = 0, T _z = 0) : x(_x), y(_y), z(_z) { }
366
367 operator Vector2<T>()const{return Vector2<T>(x,y);}
368 };
369
370 template <class T>
371 Vector3<T> operator*(T s, const Vector3<T> &a)
372 {
373 return a * s;
374 }
375
376
377 template <class T> struct Vector4
378 {
379 union
380 {
381 struct
382 {
383 T x;
384 T y;
385 T z;
386 T w;
387 };
388 struct
389 {
390 T r;
391 T g;
392 T b;
393 T a;
394 };
395 };
396
397 Vector4 operator-( const Vector4 &right)const
398 {
399 return Vector4(x - right.x, y - right.y, z - right.z, w - right.w);
400 }
401
402 Vector4 operator-()const
403 {
404 return Vector4(-x, -y, -z, -w);
405 }
406
407 Vector4& operator-=(const Vector4<T> &right)
408 {
409 x -= right.x;
410 y -= right.y;
411 z -= right.z;
412 w -= right.w;
413 return *this;
414 }
415
416 Vector4 operator+( const Vector4 &right)const
417 {
418 return Vector4(x + right.x, y + right.y, z + right.z, w + right.w);
419 }
420
421 Vector4& operator+=(const Vector4<T> &right)
422 {
423 x += right.x;
424 y += right.y;
425 z += right.z;
426 w += right.w;
427 return *this;
428 }
429
430 Vector4 operator*( T s)const
431 {
432 return Vector4(x * s, y * s, z * s, w * s);
433 }
434
435 Vector4& operator*=( T s)
436 {
437 x *= s;
438 y *= s;
439 z *= s;
440 w *= s;
441 return *this;
442 }
443
444 Vector4 operator*( const Vector4 &right)const
445 {
446 return Vector4(x * right.x, y * right.y, z * right.z, w * right.w);
447 }
448
449 Vector4& operator*=( const Vector4 &right)
450 {
451 x *= right.x;
452 y *= right.y;
453 z *= right.z;
454 w *= right.w;
455 return *this;
456 }
457
458 Vector4 operator/( T s)const
459 {
460 return Vector4(x / s, y / s, z / s, w / s);
461 }
462
463 Vector4& operator/=( T s)
464 {
465 x /= s;
466 y /= s;
467 z /= s;
468 w /= s;
469 return *this;
470 }
471
472 Vector4 operator/( const Vector4 &right)const
473 {
474 return Vector4(x / right.x, y / right.y, z / right.z, w / right.w);
475 }
476
477 Vector4& operator/=( const Vector4 &right)
478 {
479 x /= right.x;
480 y /= right.y;
481 z /= right.z;
482 w /= right.w;
483 return *this;
484 }
485
486 bool operator == (const Vector4 &right)const
487 {
488 return x == right.x && y == right.y && z == right.z && w == right.w;
489 }
490
491 bool operator != (const Vector4 &right)const
492 {
493 return !(*this == right);
494 }
495
496 Vector4 operator*(const Matrix4x4<T>& m)const
497 {
498 Vector4 out;
499 out[0] = x * m[0][0] + y * m[1][0] + z * m[2][0] + w * m[3][0];
500 out[1] = x * m[0][1] + y * m[1][1] + z * m[2][1] + w * m[3][1];
501 out[2] = x * m[0][2] + y * m[1][2] + z * m[2][2] + w * m[3][2];
502 out[3] = x * m[0][3] + y * m[1][3] + z * m[2][3] + w * m[3][3];
503 return out;
504 }
505
506 Vector4& operator = (const Vector3<T> &v3)
507 {
508 x = v3.x;
509 y = v3.y;
510 z = v3.z;
511 w = 1;
512 return *this;
513 }
514 Vector4& operator = (const Vector4 &) = default;
515
516 Vector4 operator < ( const Vector4 &right )const
517 {
518 return Vector4(x < right.x ? static_cast<T>(1) : static_cast<T>(0),
519 y < right.y ? static_cast<T>(1) : static_cast<T>(0),
520 z < right.z ? static_cast<T>(1) : static_cast<T>(0),
521 w < right.w ? static_cast<T>(1) : static_cast<T>(0));
522 }
523
524 Vector4 operator > ( const Vector4 &right )const
525 {
526 return Vector4(x > right.x ? static_cast<T>(1) : static_cast<T>(0),
527 y > right.y ? static_cast<T>(1) : static_cast<T>(0),
528 z > right.z ? static_cast<T>(1) : static_cast<T>(0),
529 w > right.w ? static_cast<T>(1) : static_cast<T>(0));
530 }
531
532 Vector4 operator <= ( const Vector4 &right )const
533 {
534 return Vector4(x <= right.x ? static_cast<T>(1) : static_cast<T>(0),
535 y <= right.y ? static_cast<T>(1) : static_cast<T>(0),
536 z <= right.z ? static_cast<T>(1) : static_cast<T>(0),
537 w <= right.w ? static_cast<T>(1) : static_cast<T>(0));
538 }
539
540 Vector4 operator >= ( const Vector4 &right )const
541 {
542 return Vector4(x >= right.x ? static_cast<T>(1) : static_cast<T>(0),
543 y >= right.y ? static_cast<T>(1) : static_cast<T>(0),
544 z >= right.z ? static_cast<T>(1) : static_cast<T>(0),
545 w >= right.w ? static_cast<T>(1) : static_cast<T>(0));
546 }
547
548 T& operator[](size_t index)
549 {
550 return reinterpret_cast<T*>(this)[index];
551 }
552
553 const T& operator[](size_t index)const
554 {
555 return reinterpret_cast<const T*>(this)[index];
556 }
557
558 explicit
559 Vector4(T _x = 0, T _y = 0, T _z = 0, T _w = 0) : x(_x), y(_y), z(_z), w(_w) { }
560 };
561
562
563 template <class T>
564 Vector4<T> operator*(T s, const Vector4<T> &a)
565 {
566 return a * s;
567 }
568
569 template <class T> struct Matrix3x3
570 {
571 union
572 {
573 struct
574 {
575 T _11; T _12; T _13;
576 T _21; T _22; T _23;
577 T _31; T _32; T _33;
578 };
579 struct
580 {
581 T _m00; T _m01; T _m02;
582 T _m10; T _m11; T _m12;
583 T _m20; T _m21; T _m22;
584 };
585 };
586
587 explicit
588 Matrix3x3(T value = 0)
589 {
590 _11 = _12 = _13 =value;
591 _21 = _22 = _23 =value;
592 _31 = _32 = _33 =value;
593 }
594
595 explicit
596 Matrix3x3(
597 T i11, T i12, T i13,
598 T i21, T i22, T i23,
599 T i31, T i32, T i33 )
600 {
601 _11 = i11; _12 = i12; _13 = i13;
602 _21 = i21; _22 = i22; _23 = i23;
603 _31 = i31; _32 = i32; _33 = i33;
604 }
605
606 bool operator == (const Matrix3x3 &r)const
607 {
608 for( int i = 0; i < 3; ++i )
609 for( int j = 0; i < 3; ++i )
610 if( (*this)[i][j] != r[i][j] )
611 return false;
612
613 return true;
614 }
615
616 bool operator != (const Matrix3x3 &r)const
617 {
618 return !(*this == r);
619 }
620
621 T* operator[](size_t index)
622 {
623 return &(reinterpret_cast<T*>(this)[index*3]);
624 }
625
626 const T* operator[](size_t index)const
627 {
628 return &(reinterpret_cast<const T*>(this)[index*3]);
629 }
630
631 Matrix3x3& operator *=(T s)
632 {
633 for( int i = 0; i < 9; ++i )
634 (reinterpret_cast<T*>(this))[i] *= s;
635
636 return *this;
637 }
638 };
639
640 template <class T> struct Matrix4x4
641 {
642 union
643 {
644 struct
645 {
646 T _11; T _12; T _13; T _14;
647 T _21; T _22; T _23; T _24;
648 T _31; T _32; T _33; T _34;
649 T _41; T _42; T _43; T _44;
650 };
651 struct
652 {
653 T _m00; T _m01; T _m02; T _m03;
654 T _m10; T _m11; T _m12; T _m13;
655 T _m20; T _m21; T _m22; T _m23;
656 T _m30; T _m31; T _m32; T _m33;
657 };
658 };
659
660 explicit
661 Matrix4x4(T value = 0)
662 {
663 _11 = _12 = _13 = _14 = value;
664 _21 = _22 = _23 = _24 = value;
665 _31 = _32 = _33 = _34 = value;
666 _41 = _42 = _43 = _44 = value;
667 }
668
669 explicit
670 Matrix4x4(
671 T i11, T i12, T i13, T i14,
672 T i21, T i22, T i23, T i24,
673 T i31, T i32, T i33, T i34,
674 T i41, T i42, T i43, T i44
675 )
676 {
677 _11 = i11; _12 = i12; _13 = i13; _14 = i14;
678 _21 = i21; _22 = i22; _23 = i23; _24 = i24;
679 _31 = i31; _32 = i32; _33 = i33; _34 = i34;
680 _41 = i41; _42 = i42; _43 = i43; _44 = i44;
681 }
682
683 bool operator == (const Matrix4x4 &r)const
684 {
685 for( int i = 0; i < 4; ++i )
686 for( int j = 0; i < 4; ++i )
687 if( (*this)[i][j] != r[i][j] )
688 return false;
689
690 return true;
691 }
692
693 bool operator != (const Matrix4x4 &r)const
694 {
695 return !(*this == r);
696 }
697
698 T* operator[](size_t index)
699 {
700 return &(reinterpret_cast<T*>(this)[index*4]);
701 }
702
703 const T* operator[](size_t index)const
704 {
705 return &(reinterpret_cast<const T*>(this)[index*4]);
706 }
707
708 Matrix4x4& operator *=(T s)
709 {
710 for( int i = 0; i < 16; ++i )
711 (reinterpret_cast<T*>(this))[i] *= s;
712
713 return *this;
714 }
715 };
716
717 // Template Vector Operations
718
719
720 template <class T>
721 T dot(const Vector2<T> &a, const Vector2<T> &b)
722 {
723 return a.x * b.x + a.y * b.y;
724 }
725
726 template <class T>
727 T dot(const Vector3<T> &a, const Vector3<T> &b)
728 {
729 return a.x * b.x + a.y * b.y + a.z * b.z;
730 }
731
732 template <class T>
733 T dot(const Vector4<T> &a, const Vector4<T> &b)
734 {
735 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
736 }
737
738 template <class VectorType>
739 auto length(const VectorType &a)->decltype(dot(a,a))
740 {
741 return sqrt( dot(a,a) );
742 }
743
744
745 template <class T>
746 Vector3<T> min(const Vector3<T> &a, const Vector3<T> &b)
747 {
748 return Vector3<T>( std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z) );
749 }
750
751 template <class T>
752 Vector4<T> min(const Vector4<T> &a, const Vector4<T> &b)
753 {
754 return Vector4<T>( std::min(a.x, b.x), std::min(a.y, b.y), std::min(a.z, b.z), std::min(a.w, b.w) );
755 }
756
757 template <class T>
758 Vector3<T> max(const Vector3<T> &a, const Vector3<T> &b)
759 {
760 return Vector3<T>( std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z) );
761 }
762
763 template <class T>
764 Vector4<T> max(const Vector4<T> &a, const Vector4<T> &b)
765 {
766 return Vector4<T>( std::max(a.x, b.x), std::max(a.y, b.y), std::max(a.z, b.z), std::max(a.w, b.w) );
767 }
768
769 template <class T>
770 Vector2<T> abs(const Vector2<T> &a)
771 {
772 // WARNING: abs() on gcc is for integers only!
773 return Vector2<T>( a.x < 0 ? -a.x : a.x,
774 a.y < 0 ? -a.y : a.y);
775 }
776
777 template <class T>
778 Vector3<T> abs(const Vector3<T> &a)
779 {
780 // WARNING: abs() on gcc is for integers only!
781 return Vector3<T>( a.x < 0 ? -a.x : a.x,
782 a.y < 0 ? -a.y : a.y,
783 a.z < 0 ? -a.z : a.z);
784 }
785
786 template <class T>
787 Vector4<T> abs(const Vector4<T> &a)
788 {
789 // WARNING: abs() on gcc is for integers only!
790 return Vector4<T>( a.x < 0 ? -a.x : a.x,
791 a.y < 0 ? -a.y : a.y,
792 a.z < 0 ? -a.z : a.z,
793 a.w < 0 ? -a.w : a.w);
794 }
795
796
797 template <class T>
798 Vector3<T> cross(const Vector3<T> &a, const Vector3<T> &b)
799 {
800 // | i j k |
801 // | a.x a.y a.z |
802 // | b.x b.y b.z |
803 return Vector3<T>((a.y*b.z)-(a.z*b.y), (a.z*b.x)-(a.x*b.z), (a.x*b.y)-(a.y*b.x));
804 }
805
806 template <class VectorType>
807 VectorType normalize(const VectorType &a)
808 {
809 auto len = length(a);
810 return a / len;
811 }
812
813
814 // Template Matrix Operations
815
816 template <class T>
817 Matrix4x4<T> transposeMatrix(const Matrix4x4<T> &m)
818 {
819 return Matrix4x4<T>(
820 m._11, m._21, m._31, m._41,
821 m._12, m._22, m._32, m._42,
822 m._13, m._23, m._33, m._43,
823 m._14, m._24, m._34, m._44
824 );
825 }
826
827 template <class T>
828 Matrix4x4<T> mul(const Matrix4x4<T> &m1, const Matrix4x4<T> &m2)
829 {
830 Matrix4x4<T> mOut;
831
832 for (int i = 0; i < 4; i++)
833 {
834 for (int j = 0; j < 4; j++)
835 {
836 for (int k = 0; k < 4; k++)
837 {
838 mOut[i][j] += m1[i][k] * m2[k][j];
839 }
840 }
841 }
842
843 return mOut;
844 }
845
846 template <class T>
847 Matrix4x4<T> operator* (const Matrix4x4<T> &m1, const Matrix4x4<T> &m2)
848 {
849 return mul( m1, m2 );
850 }
851
852
853
854 template <class T>
855 Matrix3x3<T> transposeMatrix(const Matrix3x3<T> &m)
856 {
857 return Matrix3x3<T>(
858 m._11, m._21, m._31,
859 m._12, m._22, m._32,
860 m._13, m._23, m._33
861 );
862 }
863
864 template <class T>
865 Matrix3x3<T> mul(const Matrix3x3<T> &m1, const Matrix3x3<T> &m2)
866 {
867 Matrix3x3<T> mOut;
868
869 for (int i = 0; i < 3; i++)
870 {
871 for (int j = 0; j < 3; j++)
872 {
873 for (int k = 0; k < 3; k++)
874 {
875 mOut[i][j] += m1[i][k] * m2[k][j];
876 }
877 }
878 }
879
880 return mOut;
881 }
882
883 template <class T>
884 Matrix3x3<T> operator* (const Matrix3x3<T> &m1, const Matrix3x3<T> &m2)
885 {
886 return mul( m1, m2 );
887 }
888
889 // Common HLSL-compatible vector typedefs
890
891 typedef unsigned int uint;
892
893 typedef Vector2<float> float2;
894 typedef Vector3<float> float3;
895 typedef Vector4<float> float4;
896
897 typedef Matrix4x4<float> float4x4;
898 typedef Matrix3x3<float> float3x3;
899
900 // Standard Matrix Intializers
901
902 inline float4x4 identityMatrix()
903 {
904 return float4x4(1, 0, 0, 0,
905 0, 1, 0, 0,
906 0, 0, 1, 0,
907 0, 0, 0, 1);
908 }
909
910 inline float4x4 translationMatrix(float x, float y, float z)
911 {
912 return float4x4 (1, 0, 0, 0,
913 0, 1, 0, 0,
914 0, 0, 1, 0,
915 x, y, z, 1);
916 }
917
918 inline float4x4 translationMatrix( const float3 &v )
919 {
920 return translationMatrix( v.x, v.y, v.z );
921 }
922
923
924 inline float4x4 scaleMatrix(float x, float y, float z)
925 {
926 return float4x4(x, 0, 0, 0,
927 0, y, 0, 0,
928 0, 0, z, 0,
929 0, 0, 0, 1);
930 }
931
932 inline float4x4 rotationX(float angleInRadians)
933 {
934 float sinAngle = sinf(angleInRadians);
935 float cosAngle = cosf(angleInRadians);
936
937 float4x4 mOut;
938
939 mOut._11 = 1.0f; mOut._12 = 0.0f; mOut._13 = 0.0f; mOut._14 = 0.0f;
940 mOut._21 = 0.0f; mOut._22 = cosAngle; mOut._23 = -sinAngle; mOut._24 = 0.0f;
941 mOut._31 = 0.0f; mOut._32 = sinAngle; mOut._33 = cosAngle; mOut._34 = 0.0f;
942 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
943
944 return mOut;
945 }
946
947 inline float4x4 rotationY(float angleInRadians)
948 {
949 float sinAngle = sinf(angleInRadians);
950 float cosAngle = cosf(angleInRadians);
951
952 float4x4 mOut;
953
954 mOut._11 = cosAngle; mOut._12 = 0.0f; mOut._13 = sinAngle; mOut._14 = 0.0f;
955 mOut._21 = 0.0f; mOut._22 = 1.0f; mOut._23 = 0.0f; mOut._24 = 0.0f;
956 mOut._31 = -sinAngle; mOut._32 = 0.0f; mOut._33 = cosAngle; mOut._34 = 0.0f;
957 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
958
959 return mOut;
960 }
961
962 inline float4x4 rotationZ(float angleInRadians)
963 {
964 float sinAngle = sinf(angleInRadians);
965 float cosAngle = cosf(angleInRadians);
966
967 float4x4 mOut;
968
969 mOut._11 = cosAngle; mOut._12 = -sinAngle; mOut._13 = 0.0f; mOut._14 = 0.0f;
970 mOut._21 = sinAngle; mOut._22 = cosAngle; mOut._23 = 0.0f; mOut._24 = 0.0f;
971 mOut._31 = 0.0f; mOut._32 = 0.0f; mOut._33 = 1.0f; mOut._34 = 0.0f;
972 mOut._41 = 0.0f; mOut._42 = 0.0f; mOut._43 = 0.0f; mOut._44 = 1.0f;
973
974 return mOut;
975 }
976
977 // 3D Rotation matrix for an arbitrary axis specified by x, y and z
978 inline float4x4 rotationArbitrary(float3 axis, float degree)
979 {
980 UNSUPPORTED("This function is not tested, it might be incorrect");
981
982 axis = normalize(axis);
983
984 float angleInRadians = degree * (PI_F / 180.0f);
985
986 float sinAngle = sinf(angleInRadians);
987 float cosAngle = cosf(angleInRadians);
988 float oneMinusCosAngle = 1 - cosAngle;
989
990 float4x4 mOut;
991
992 mOut._11 = 1.0f + oneMinusCosAngle * (axis.x * axis.x - 1.0f);
993 mOut._12 = axis.z * sinAngle + oneMinusCosAngle * axis.x * axis.y;
994 mOut._13 = -axis.y * sinAngle + oneMinusCosAngle * axis.x * axis.z;
995 mOut._41 = 0.0f;
996
997 mOut._21 = -axis.z * sinAngle + oneMinusCosAngle * axis.y * axis.x;
998 mOut._22 = 1.0f + oneMinusCosAngle * (axis.y * axis.y - 1.0f);
999 mOut._23 = axis.x * sinAngle + oneMinusCosAngle * axis.y * axis.z;
1000 mOut._24 = 0.0f;
1001
1002 mOut._31 = axis.y * sinAngle + oneMinusCosAngle * axis.z * axis.x;
1003 mOut._32 = -axis.x * sinAngle + oneMinusCosAngle * axis.z * axis.y;
1004 mOut._33 = 1.0f + oneMinusCosAngle * (axis.z * axis.z - 1.0f);
1005 mOut._34 = 0.0f;
1006
1007 mOut._41 = 0.0f;
1008 mOut._42 = 0.0f;
1009 mOut._43 = 0.0f;
1010 mOut._44 = 1.0f;
1011
1012 return mOut;
1013 }
1014
1015 inline float4x4 ViewMatrixFromBasis( const float3 &f3X, const float3 &f3Y, const float3 &f3Z )
1016 {
1017 return float4x4( f3X.x, f3Y.x, f3Z.x, 0,
1018 f3X.y, f3Y.y, f3Z.y, 0,
1019 f3X.z, f3Y.z, f3Z.z, 0,
1020 0, 0, 0, 1);
1021 }
1022
1023 inline void SetNearFarClipPlanes( float4x4 &ProjMatrix, float zNear, float zFar, bool bIsDirectX )
1024 {
1025 if( bIsDirectX )
1026 {
1027 ProjMatrix._33 = zFar / (zFar - zNear);
1028 ProjMatrix._43 = -zNear * zFar / (zFar - zNear);
1029 ProjMatrix._34 = 1;
1030 }
1031 else
1032 {
1033 // https://www.opengl.org/sdk/docs/man2/xhtml/gluPerspective.xml
1034 // http://www.terathon.com/gdc07_lengyel.pdf
1035 // Note that OpenGL uses right-handed coordinate system, where
1036 // camera is looking in negative z direction:
1037 // OO
1038 // |__|<--------------------
1039 // -z +z
1040 // Consequently, OpenGL projection matrix given by these two
1041 // references inverts z axis.
1042
1043 // We do not need to do this, because we use DX coordinate
1044 // system for the camera space. Thus we need to invert the
1045 // sign of the values in the third column in the matrix
1046 // from the references:
1047
1048 ProjMatrix._33 = -(-(zFar + zNear) / (zFar - zNear));
1049 ProjMatrix._43 = -2.0f * zNear * zFar / (zFar - zNear);
1050 ProjMatrix._34 = -(-1);
1051 }
1052 }
1053
1054 inline void GetNearFarPlaneFromProjMatrix( const float4x4 &ProjMatrix, float &zNear, float &zFar, bool bIsDirectX )
1055 {
1056 if( bIsDirectX )
1057 {
1058 zNear = -ProjMatrix._43 / ProjMatrix._33;
1059 zFar = ProjMatrix._33 / (ProjMatrix._33 - 1) * zNear;
1060 }
1061 else
1062 {
1063 zNear = ProjMatrix._43 / (-1.f - ProjMatrix._33);
1064 zFar = ProjMatrix._43 / (+1.f - ProjMatrix._33);
1065 }
1066 }
1067
1068 inline float4x4 Projection(float fov, float aspectRatio, float zNear, float zFar, bool bIsDirectX) // Left-handed projection
1069 {
1070 float4x4 mOut;
1071 float yScale = 1.0f / tan(fov / 2.0f);
1072 float xScale = yScale / aspectRatio;
1073 mOut._11 = xScale;
1074 mOut._22 = yScale;
1075
1076 SetNearFarClipPlanes( mOut, zNear, zFar, bIsDirectX );
1077
1078 return mOut;
1079 }
1080
1081
1082 struct Quaternion
1083 {
1084 float q[4];
1085 };
1086
1087 inline Quaternion RotationFromAxisAngle(const float3& axis, float angle)
1088 {
1089 Quaternion out;
1090 float norm = length(axis);
1091 float sina2 = sin(0.5f * angle);
1092 out.q[0] = sina2 * axis[0] / norm;
1093 out.q[1] = sina2 * axis[1] / norm;
1094 out.q[2] = sina2 * axis[2] / norm;
1095 out.q[3] = cos(0.5f * angle);
1096 return out;
1097 }
1098
1099 inline void AxisAngleFromRotation(float3& outAxis, float& outAngle, const Quaternion& quat)
1100 {
1101 float sina2 = sqrt(quat.q[0]*quat.q[0] + quat.q[1]*quat.q[1] + quat.q[2]*quat.q[2]);
1102 outAngle = 2.0f * atan2(sina2, quat.q[3]);
1103 float r = (sina2 > 0) ? (1.0f / sina2) : 0;
1104 outAxis[0] = r * quat.q[0];
1105 outAxis[1] = r * quat.q[1];
1106 outAxis[2] = r * quat.q[2];
1107 }
1108
1109 inline float4x4 QuaternionToMatrix(const Quaternion& quat)
1110 {
1111 float4x4 out;
1112 float yy2 = 2.0f * quat.q[1] * quat.q[1];
1113 float xy2 = 2.0f * quat.q[0] * quat.q[1];
1114 float xz2 = 2.0f * quat.q[0] * quat.q[2];
1115 float yz2 = 2.0f * quat.q[1] * quat.q[2];
1116 float zz2 = 2.0f * quat.q[2] * quat.q[2];
1117 float wz2 = 2.0f * quat.q[3] * quat.q[2];
1118 float wy2 = 2.0f * quat.q[3] * quat.q[1];
1119 float wx2 = 2.0f * quat.q[3] * quat.q[0];
1120 float xx2 = 2.0f * quat.q[0] * quat.q[0];
1121 out[0][0] = - yy2 - zz2 + 1.0f;
1122 out[0][1] = xy2 + wz2;
1123 out[0][2] = xz2 - wy2;
1124 out[0][3] = 0;
1125 out[1][0] = xy2 - wz2;
1126 out[1][1] = - xx2 - zz2 + 1.0f;
1127 out[1][2] = yz2 + wx2;
1128 out[1][3] = 0;
1129 out[2][0] = xz2 + wy2;
1130 out[2][1] = yz2 - wx2;
1131 out[2][2] = - xx2 - yy2 + 1.0f;
1132 out[2][3] = 0;
1133 out[3][0] = out[3][1] = out[3][2] = 0;
1134 out[3][3] = 1;
1135 return out;
1136 }
1137
1138 inline float determinant( const float3x3& m )
1139 {
1140 float det = 0.f;
1141 det += m._11 * (m._22*m._33 - m._32*m._23);
1142 det -= m._12 * (m._21*m._33 - m._31*m._23);
1143 det += m._13 * (m._21*m._32 - m._31*m._22);
1144 return det;
1145 }
1146
1147
1148 inline float determinant( const float4x4& m )
1149 {
1150 float det = 0.f;
1151
1152 det += m._11 * determinant(
1153 float3x3 ( m._22,m._23,m._24,
1154 m._32,m._33,m._34,
1155 m._42,m._43,m._44) );
1156
1157 det -= m._12 * determinant(
1158 float3x3( m._21,m._23,m._24,
1159 m._31,m._33,m._34,
1160 m._41,m._43,m._44) );
1161
1162 det += m._13 * determinant(
1163 float3x3( m._21,m._22,m._24,
1164 m._31,m._32,m._34,
1165 m._41,m._42,m._44) );
1166
1167 det -= m._14 * determinant(
1168 float3x3( m._21,m._22,m._23,
1169 m._31,m._32,m._33,
1170 m._41,m._42,m._43) );
1171
1172 return det;
1173 }
1174
1175 inline float4x4 inverseMatrix(const float4x4& m)
1176 {
1177 float4x4 inv;
1178
1179 // row 1
1180 inv._11 = determinant(
1181 float3x3( m._22, m._23, m._24,
1182 m._32, m._33, m._34,
1183 m._42, m._43, m._44 ) );
1184
1185 inv._12 = -determinant(
1186 float3x3( m._21, m._23, m._24,
1187 m._31, m._33, m._34,
1188 m._41, m._43, m._44) );
1189
1190 inv._13 = determinant(
1191 float3x3 ( m._21, m._22, m._24,
1192 m._31, m._32, m._34,
1193 m._41, m._42, m._44) );
1194
1195 inv._14 = -determinant(
1196 float3x3 ( m._21, m._22, m._23,
1197 m._31, m._32, m._33,
1198 m._41, m._42, m._43) );
1199
1200
1201 // row 2
1202 inv._21 = -determinant(
1203 float3x3( m._12, m._13, m._14,
1204 m._32, m._33, m._34,
1205 m._42, m._43, m._44) );
1206
1207 inv._22 = determinant(
1208 float3x3( m._11, m._13, m._14,
1209 m._31, m._33, m._34,
1210 m._41, m._43, m._44) );
1211
1212 inv._23 = -determinant(
1213 float3x3( m._11, m._12, m._14,
1214 m._31, m._32, m._34,
1215 m._41, m._42, m._44) );
1216
1217 inv._24 = determinant(
1218 float3x3( m._11, m._12, m._13,
1219 m._31, m._32, m._33,
1220 m._41, m._42, m._43) );
1221
1222
1223 // row 3
1224 inv._31 = determinant(
1225 float3x3( m._12,m._13,m._14,
1226 m._22,m._23,m._24,
1227 m._42,m._43,m._44) );
1228
1229 inv._32 = -determinant(
1230 float3x3( m._11,m._13,m._14,
1231 m._21,m._23,m._24,
1232 m._41,m._43,m._44) );
1233
1234 inv._33 = determinant(
1235 float3x3( m._11,m._12,m._14,
1236 m._21,m._22,m._24,
1237 m._41,m._42,m._44) );
1238
1239 inv._34 = -determinant(
1240 float3x3( m._11,m._12,m._13,
1241 m._21,m._22,m._23,
1242 m._41,m._42,m._43) );
1243
1244 // row 4
1245 inv._41 = -determinant(
1246 float3x3( m._12, m._13, m._14,
1247 m._22, m._23, m._24,
1248 m._32, m._33, m._34) );
1249
1250 inv._42 = determinant(
1251 float3x3( m._11, m._13, m._14,
1252 m._21, m._23, m._24,
1253 m._31, m._33, m._34) );
1254
1255 inv._43 = -determinant(
1256 float3x3( m._11, m._12, m._14,
1257 m._21, m._22, m._24,
1258 m._31, m._32, m._34) );
1259
1260 inv._44 = determinant(
1261 float3x3( m._11, m._12, m._13,
1262 m._21, m._22, m._23,
1263 m._31, m._32, m._33) );
1264
1265 auto det = m._11 * inv._11 + m._12 * inv._12 + m._13 * inv._13 + m._14 * inv._14;
1266 inv = transposeMatrix(inv);
1267 inv *= 1.0f/det;
1268
1269 return inv;
1270 }
1271
1272 namespace std
1273 {
1274 template<typename T>
1275 Vector2<T> max( const Vector2<T> &Left, const Vector2<T> &Right )
1276 {
1277 return Vector2<T>(
1278 std::max( Left.x, Right.x ),
1279 std::max( Left.y, Right.y )
1280 );
1281 }
1282
1283 template<typename T>
1284 Vector3<T> max( const Vector3<T> &Left, const Vector3<T> &Right )
1285 {
1286 return Vector3<T>(
1287 std::max( Left.x, Right.x ),
1288 std::max( Left.y, Right.y ),
1289 std::max( Left.z, Right.z )
1290 );
1291 }
1292
1293 template<typename T>
1294 Vector4<T> max( const Vector4<T> &Left, const Vector4<T> &Right )
1295 {
1296 return Vector4<T>(
1297 std::max( Left.x, Right.x ),
1298 std::max( Left.y, Right.y ),
1299 std::max( Left.z, Right.z ),
1300 std::max( Left.w, Right.w )
1301 );
1302 }
1303
1304
1305 template<typename T>
1306 Vector2<T> min( const Vector2<T> &Left, const Vector2<T> &Right )
1307 {
1308 return Vector2<T>(
1309 std::min( Left.x, Right.x ),
1310 std::min( Left.y, Right.y )
1311 );
1312 }
1313
1314 template<typename T>
1315 Vector3<T> min( const Vector3<T> &Left, const Vector3<T> &Right )
1316 {
1317 return Vector3<T>(
1318 std::min( Left.x, Right.x ),
1319 std::min( Left.y, Right.y ),
1320 std::min( Left.z, Right.z )
1321 );
1322 }
1323
1324 template<typename T>
1325 Vector4<T> min( const Vector4<T> &Left, const Vector4<T> &Right )
1326 {
1327 return Vector4<T>(
1328 std::min( Left.x, Right.x ),
1329 std::min( Left.y, Right.y ),
1330 std::min( Left.z, Right.z ),
1331 std::min( Left.w, Right.w )
1332 );
1333 }
1334
1335
1336 template<typename T>
1337 struct hash<Vector2<T>>
1338 {
1339 size_t operator()( const Vector2<T> &v2 ) const
1340 {
1341 return Diligent::ComputeHash(v2.x, v2.y);
1342 }
1343 };
1344
1345 template<typename T>
1346 struct hash<Vector3<T>>
1347 {
1348 size_t operator()( const Vector3<T> &v3 ) const
1349 {
1350 return Diligent::ComputeHash(v3.x, v3.y, v3.z);
1351 }
1352 };
1353
1354 template<typename T>
1355 struct hash<Vector4<T>>
1356 {
1357 size_t operator()( const Vector4<T> &v4 ) const
1358 {
1359 return Diligent::ComputeHash(v4.x, v4.y, v4.z, v4.w);
1360 }
1361 };
1362
1363 template<typename T>
1364 struct hash<Matrix3x3<T>>
1365 {
1366 size_t operator()( const Matrix3x3<T> &m ) const
1367 {
1368 return Diligent::ComputeHash(
1369 m._m00, m._m01, m._m02,
1370 m._m10, m._m11, m._m12,
1371 m._m20, m._m21, m._m22
1372 );
1373 }
1374 };
1375
1376 template<typename T>
1377 struct hash<Matrix4x4<T>>
1378 {
1379 size_t operator()( const Matrix4x4<T> &m ) const
1380 {
1381 return Diligent::ComputeHash(
1382 m._m00, m._m01, m._m02, m._m03,
1383 m._m10, m._m11, m._m12, m._m13,
1384 m._m20, m._m21, m._m22, m._m23,
1385 m._m30, m._m31, m._m32, m._m33
1386 );
1387 }
1388 };
1389 }
std
Definition: AdvancedMath.h:316