Blender V4.3
BLI_math_matrix_types.hh
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2022 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
34#include <array>
35#include <cmath>
36#include <ostream>
37#include <type_traits>
38
40#include "BLI_utildefines.h"
41#include "BLI_utility_mixins.hh"
42
43namespace blender {
44
45template<typename T,
46 int NumCol,
47 int NumRow,
48 int SrcNumCol,
49 int SrcNumRow,
50 int SrcStartCol,
51 int SrcStartRow,
52 int Alignment>
53struct MatView;
54
55template<typename T,
56 int NumCol,
57 int NumRow,
58 int SrcNumCol,
59 int SrcNumRow,
60 int SrcStartCol,
61 int SrcStartRow,
62 int Alignment>
63struct MutableMatView;
64
65template<
66 /* Number type. */
67 typename T,
68 /* Number of column in the matrix. */
69 int NumCol,
70 /* Number of row in the matrix. */
71 int NumRow,
72 /* Alignment in bytes. Do not align matrices whose size is not a multiple of 4 component.
73 * This is in order to avoid padding when using arrays of matrices. */
74 int Alignment = (((NumCol * NumRow) % 4 == 0) ? 4 : 1) * sizeof(T)>
75struct alignas(Alignment) MatBase : public vec_struct_base<VecBase<T, NumRow>, NumCol> {
76
77 using base_type = T;
81 using loc_type = VecBase<T, (NumRow < NumCol) ? NumRow : (NumRow - 1)>;
82 static constexpr int min_dim = (NumRow < NumCol) ? NumRow : NumCol;
83 static constexpr int col_len = NumCol;
84 static constexpr int row_len = NumRow;
85
86 MatBase() = default;
87
88/* Workaround issue with template BLI_ENABLE_IF((Size == 2)) not working. */
89#define BLI_ENABLE_IF_MAT(_size, _test) int S = _size, BLI_ENABLE_IF((S _test))
90
91 template<BLI_ENABLE_IF_MAT(NumCol, == 2)> MatBase(col_type _x, col_type _y)
92 {
93 (*this)[0] = _x;
94 (*this)[1] = _y;
95 }
96
97 template<BLI_ENABLE_IF_MAT(NumCol, == 3)> MatBase(col_type _x, col_type _y, col_type _z)
98 {
99 (*this)[0] = _x;
100 (*this)[1] = _y;
101 (*this)[2] = _z;
102 }
103
104 template<BLI_ENABLE_IF_MAT(NumCol, == 4)>
106 {
107 (*this)[0] = _x;
108 (*this)[1] = _y;
109 (*this)[2] = _z;
110 (*this)[3] = _w;
111 }
112
115 template<typename U, int OtherNumCol, int OtherNumRow>
117 {
118 if constexpr ((OtherNumRow >= NumRow) && (OtherNumCol >= NumCol)) {
119 unroll<NumCol>([&](auto i) { (*this)[i] = col_type(other[i]); });
120 }
121 else {
122 /* Allow enlarging following GLSL standard (i.e: mat4x4(mat3x3())). */
123 unroll<NumCol>([&](auto i) {
124 unroll<NumRow>([&](auto j) {
125 if (i < OtherNumCol && j < OtherNumRow) {
126 (*this)[i][j] = other[i][j];
127 }
128 else if (i == j) {
129 (*this)[i][j] = T(1);
130 }
131 else {
132 (*this)[i][j] = T(0);
133 }
134 });
135 });
136 }
137 }
138
139#undef BLI_ENABLE_IF_MAT
140
143 explicit MatBase(const T *ptr)
144 {
145 unroll<NumCol>([&](auto i) { (*this)[i] = reinterpret_cast<const col_type *>(ptr)[i]; });
146 }
147
148 template<typename U, BLI_ENABLE_IF((std::is_convertible_v<U, T>))> explicit MatBase(const U *ptr)
149 {
150 unroll<NumCol>([&](auto i) { (*this)[i] = ptr[i]; });
151 }
152
153 explicit MatBase(const T (*ptr)[NumCol]) : MatBase(static_cast<const T *>(ptr[0])) {}
154
157 template<typename U> explicit MatBase(const MatBase<U, NumRow, NumCol> &vec)
158 {
159 unroll<NumCol>([&](auto i) { (*this)[i] = col_type(vec[i]); });
160 }
161
164 using c_style_mat = T[NumCol][NumRow];
165
167 const c_style_mat &ptr() const
168 {
169 return *reinterpret_cast<const c_style_mat *>(this);
170 }
171
174 {
175 return *reinterpret_cast<c_style_mat *>(this);
176 }
177
179 const T *base_ptr() const
180 {
181 return reinterpret_cast<const T *>(this);
182 }
183
186 {
187 return reinterpret_cast<T *>(this);
188 }
189
192 template<int ViewNumCol = NumCol,
193 int ViewNumRow = NumRow,
194 int SrcStartCol = 0,
195 int SrcStartRow = 0>
202
203 template<int ViewNumCol = NumCol,
204 int ViewNumRow = NumRow,
205 int SrcStartCol = 0,
206 int SrcStartRow = 0>
209 {
210 return MutableMatView<T,
211 ViewNumCol,
212 ViewNumRow,
213 NumCol,
214 NumRow,
215 SrcStartCol,
216 SrcStartRow,
217 Alignment>(*this);
218 }
219
222 const col_type &operator[](int index) const
223 {
224 BLI_assert(index >= 0);
225 BLI_assert(index < NumCol);
226 return reinterpret_cast<const col_type *>(this)[index];
227 }
228
230 {
231 BLI_assert(index >= 0);
232 BLI_assert(index < NumCol);
233 return reinterpret_cast<col_type *>(this)[index];
234 }
235
239 {
240 BLI_STATIC_ASSERT(NumCol >= 1, "Wrong Matrix dimension");
241 BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension");
242 return *reinterpret_cast<vec3_type *>(&(*this)[0]);
243 }
244
246 {
247 BLI_STATIC_ASSERT(NumCol >= 2, "Wrong Matrix dimension");
248 BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension");
249 return *reinterpret_cast<vec3_type *>(&(*this)[1]);
250 }
251
253 {
254 BLI_STATIC_ASSERT(NumCol >= 3, "Wrong Matrix dimension");
255 BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension");
256 return *reinterpret_cast<vec3_type *>(&(*this)[2]);
257 }
258
260 {
261 BLI_STATIC_ASSERT(NumCol >= 3, "Wrong Matrix dimension");
262 BLI_STATIC_ASSERT(NumRow >= 2, "Wrong Matrix dimension");
263 return *reinterpret_cast<loc_type *>(&(*this)[NumCol - 1]);
264 }
265
266 const vec3_type &x_axis() const
267 {
268 BLI_STATIC_ASSERT(NumCol >= 1, "Wrong Matrix dimension");
269 BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension");
270 return *reinterpret_cast<const vec3_type *>(&(*this)[0]);
271 }
272
273 const vec3_type &y_axis() const
274 {
275 BLI_STATIC_ASSERT(NumCol >= 2, "Wrong Matrix dimension");
276 BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension");
277 return *reinterpret_cast<const vec3_type *>(&(*this)[1]);
278 }
279
280 const vec3_type &z_axis() const
281 {
282 BLI_STATIC_ASSERT(NumCol >= 3, "Wrong Matrix dimension");
283 BLI_STATIC_ASSERT(NumRow >= 3, "Wrong Matrix dimension");
284 return *reinterpret_cast<const vec3_type *>(&(*this)[2]);
285 }
286
287 const loc_type &location() const
288 {
289 BLI_STATIC_ASSERT(NumCol >= 3, "Wrong Matrix dimension");
290 BLI_STATIC_ASSERT(NumRow >= 2, "Wrong Matrix dimension");
291 return *reinterpret_cast<const loc_type *>(&(*this)[NumCol - 1]);
292 }
293
296 friend MatBase operator+(const MatBase &a, const MatBase &b)
297 {
299 unroll<NumCol>([&](auto i) { result[i] = a[i] + b[i]; });
300 return result;
301 }
302
303 friend MatBase operator+(const MatBase &a, T b)
304 {
306 unroll<NumCol>([&](auto i) { result[i] = a[i] + b; });
307 return result;
308 }
309
310 friend MatBase operator+(T a, const MatBase &b)
311 {
312 return b + a;
313 }
314
316 {
317 unroll<NumCol>([&](auto i) { (*this)[i] += b[i]; });
318 return *this;
319 }
320
322 {
323 unroll<NumCol>([&](auto i) { (*this)[i] += b; });
324 return *this;
325 }
326
327 friend MatBase operator-(const MatBase &a)
328 {
330 unroll<NumCol>([&](auto i) { result[i] = -a[i]; });
331 return result;
332 }
333
334 friend MatBase operator-(const MatBase &a, const MatBase &b)
335 {
337 unroll<NumCol>([&](auto i) { result[i] = a[i] - b[i]; });
338 return result;
339 }
340
341 friend MatBase operator-(const MatBase &a, T b)
342 {
344 unroll<NumCol>([&](auto i) { result[i] = a[i] - b; });
345 return result;
346 }
347
348 friend MatBase operator-(T a, const MatBase &b)
349 {
351 unroll<NumCol>([&](auto i) { result[i] = a - b[i]; });
352 return result;
353 }
354
356 {
357 unroll<NumCol>([&](auto i) { (*this)[i] -= b[i]; });
358 return *this;
359 }
360
362 {
363 unroll<NumCol>([&](auto i) { (*this)[i] -= b; });
364 return *this;
365 }
366
368 friend MatBase operator*(const MatBase &a, T b)
369 {
371 unroll<NumCol>([&](auto i) { result[i] = a[i] * b; });
372 return result;
373 }
374
376 friend MatBase operator*(T a, const MatBase &b)
377 {
378 return b * a;
379 }
380
383 {
384 const MatBase &a = *this;
385 *this = a * b;
386 return *this;
387 }
388
391 {
392 unroll<NumCol>([&](auto i) { (*this)[i] *= b; });
393 return *this;
394 }
395
398 friend col_type operator*(const MatBase &a, const row_type &b)
399 {
400 /* This is the reference implementation.
401 * Might be overloaded with vectorized / optimized code. */
402 col_type result(0);
403 unroll<NumCol>([&](auto c) { result += b[c] * a[c]; });
404 return result;
405 }
406
408 friend row_type operator*(const col_type &a, const MatBase &b)
409 {
410 /* This is the reference implementation.
411 * Might be overloaded with vectorized / optimized code. */
412 row_type result(0);
413 unroll<NumCol>([&](auto c) { unroll<NumRow>([&](auto r) { result[c] += b[c][r] * a[r]; }); });
414 return result;
415 }
416
419 friend bool operator==(const MatBase &a, const MatBase &b)
420 {
421 for (int i = 0; i < NumCol; i++) {
422 if (a[i] != b[i]) {
423 return false;
424 }
425 }
426 return true;
427 }
428
429 friend bool operator!=(const MatBase &a, const MatBase &b)
430 {
431 return !(a == b);
432 }
433
436 static MatBase diagonal(T value)
437 {
438 MatBase result{};
439 unroll<min_dim>([&](auto i) { result[i][i] = value; });
440 return result;
441 }
442
443 static MatBase all(T value)
444 {
446 unroll<NumCol>([&](auto i) { result[i] = col_type(value); });
447 return result;
448 }
449
451 {
452 return diagonal(1);
453 }
454
455 static MatBase zero()
456 {
457 return all(0);
458 }
459
461 {
462 uint64_t h = 435109;
463 unroll<NumCol * NumRow>([&](auto i) {
464 T value = (reinterpret_cast<const T *>(this))[i];
465 h = h * 33 + *reinterpret_cast<const as_uint_type<T> *>(&value);
466 });
467 return h;
468 }
469
470 friend std::ostream &operator<<(std::ostream &stream, const MatBase &mat)
471 {
472 stream << "(\n";
473 for (int i = 0; i < NumRow; i++) {
474 stream << "(";
475 for (int j = 0; j < NumCol; j++) {
477 stream << mat[j][i];
478 if (j < NumCol - 1) {
479 stream << ", ";
480 }
481 }
482 stream << ")";
483 if (i < NumRow - 1) {
484 stream << ",";
485 }
486 stream << "\n";
487 }
488
489 stream << ")\n";
490 return stream;
491 }
492};
493
494template<typename T,
496 int NumCol,
497 int NumRow,
499 int SrcNumCol,
500 int SrcNumRow,
502 int SrcStartCol,
503 int SrcStartRow,
505 int SrcAlignment>
511
512 const SrcMatT &mat;
513
514 MatView() = delete;
515
516 MatView(const SrcMatT &src) : mat(src)
517 {
518 BLI_STATIC_ASSERT(SrcStartCol >= 0, "View does not fit source matrix dimensions");
519 BLI_STATIC_ASSERT(SrcStartRow >= 0, "View does not fit source matrix dimensions");
520 BLI_STATIC_ASSERT(SrcStartCol + NumCol <= SrcNumCol,
521 "View does not fit source matrix dimensions");
522 BLI_STATIC_ASSERT(SrcStartRow + NumRow <= SrcNumRow,
523 "View does not fit source matrix dimensions");
524 }
525
527 explicit MatView(const float (*src)[SrcNumRow])
528 : MatView(*reinterpret_cast<const SrcMatT *>(&src[0][0])){};
529
532 const col_type &operator[](int index) const
533 {
534 BLI_assert(index >= 0);
535 BLI_assert(index < NumCol);
536 return *reinterpret_cast<const col_type *>(&mat[index + SrcStartCol][SrcStartRow]);
537 }
538
541 operator MatT() const
542 {
543 MatT mat;
544 unroll<NumCol>([&](auto c) { mat[c] = (*this)[c]; });
545 return mat;
546 }
547
550 friend MatT operator+(const MatView &a, T b)
551 {
552 MatT result;
553 unroll<NumCol>([&](auto i) { result[i] = a[i] + b; });
554 return result;
555 }
556
557 friend MatT operator+(T a, const MatView &b)
558 {
559 return b + a;
560 }
561
562 friend MatT operator-(const MatView &a)
563 {
564 MatT result;
565 unroll<NumCol>([&](auto i) { result[i] = -a[i]; });
566 return result;
567 }
568
569 template<int OtherSrcNumCol,
570 int OtherSrcNumRow,
571 int OtherSrcStartCol,
572 int OtherSrcStartRow,
573 int OtherSrcAlignment>
574 friend MatT operator-(const MatView &a,
575 const MatView<T,
576 NumCol,
577 NumRow,
578 OtherSrcNumCol,
579 OtherSrcNumRow,
580 OtherSrcStartCol,
581 OtherSrcStartRow,
582 OtherSrcAlignment> &b)
583 {
584 MatT result;
585 unroll<NumCol>([&](auto i) { result[i] = a[i] - b[i]; });
586 return result;
587 }
588
589 friend MatT operator-(const MatView &a, const MatT &b)
590 {
591 return a - b.view();
592 }
593
594 template<int OtherSrcNumCol,
595 int OtherSrcNumRow,
596 int OtherSrcStartCol,
597 int OtherSrcStartRow,
598 int OtherSrcAlignment>
599 friend MatT operator-(const MatView<T,
600 NumCol,
601 NumRow,
602 OtherSrcNumCol,
603 OtherSrcNumRow,
604 OtherSrcStartCol,
605 OtherSrcStartRow,
606 OtherSrcAlignment> &a,
607 const MatView &b)
608 {
609 MatT result;
610 unroll<NumCol>([&](auto i) { result[i] = a[i] - b[i]; });
611 return result;
612 }
613
614 friend MatT operator-(const MatT &a, const MatView &b)
615 {
616 return a.view() - b;
617 }
618
619 friend MatT operator-(const MatView &a, T b)
620 {
621 MatT result;
622 unroll<NumCol>([&](auto i) { result[i] = a[i] - b; });
623 return result;
624 }
625
626 friend MatView operator-(T a, const MatView &b)
627 {
629 unroll<NumCol>([&](auto i) { result[i] = a - b[i]; });
630 return result;
631 }
632
633 MatT operator*(const MatT &b) const
634 {
635 return *this * b.view();
636 }
637
639 friend MatT operator*(const MatView &a, T b)
640 {
641 MatT result;
642 unroll<NumCol>([&](auto i) { result[i] = a[i] * b; });
643 return result;
644 }
645
647 friend MatT operator*(T a, const MatView &b)
648 {
649 return b * a;
650 }
651
654 friend col_type operator*(const MatView &a, const row_type &b)
655 {
656 /* This is the reference implementation.
657 * Might be overloaded with vectorized / optimized code. */
658 col_type result(0);
659 unroll<NumCol>([&](auto c) { result += b[c] * a[c]; });
660 return result;
661 }
662
664 friend row_type operator*(const col_type &a, const MatView &b)
665 {
666 /* This is the reference implementation.
667 * Might be overloaded with vectorized / optimized code. */
668 row_type result(0);
669 unroll<NumCol>([&](auto c) { unroll<NumRow>([&](auto r) { result[c] += b[c][r] * a[r]; }); });
670 return result;
671 }
672
675 friend bool operator==(const MatView &a, const MatView &b)
676 {
677 for (int i = 0; i < NumCol; i++) {
678 if (a[i] != b[i]) {
679 return false;
680 }
681 }
682 return true;
683 }
684
685 friend bool operator!=(const MatView &a, const MatView &b)
686 {
687 return !(a == b);
688 }
689
692 friend std::ostream &operator<<(std::ostream &stream, const MatView &mat)
693 {
694 return stream << mat->mat;
695 }
696};
697
698template<typename T,
700 int NumCol,
701 int NumRow,
703 int SrcNumCol,
704 int SrcNumRow,
706 int SrcStartCol,
707 int SrcStartRow,
709 int SrcAlignment>
711 : MatView<T, NumCol, NumRow, SrcNumCol, SrcNumRow, SrcStartCol, SrcStartRow, SrcAlignment> {
712
714 using MatViewT =
719
720 public:
721 MutableMatView() = delete;
722
723 MutableMatView(SrcMatT &src) : MatViewT(const_cast<const SrcMatT &>(src)){};
724
726 explicit MutableMatView(float src[SrcNumCol][SrcNumRow])
727 : MutableMatView(*reinterpret_cast<SrcMatT *>(&src[0][0])){};
728
732 {
733 return const_cast<col_type &>(static_cast<MatViewT &>(*this)[index]);
734 }
735
738 operator MatViewT() const
739 {
740 return MatViewT(this->mat);
741 }
742
745 template<int OtherSrcNumCol,
746 int OtherSrcNumRow,
747 int OtherSrcStartCol,
748 int OtherSrcStartRow,
749 int OtherSrcAlignment>
751 NumCol,
752 NumRow,
753 OtherSrcNumCol,
754 OtherSrcNumRow,
755 OtherSrcStartCol,
756 OtherSrcStartRow,
757 OtherSrcAlignment> &other)
758 {
760 (reinterpret_cast<const void *>(&other.mat[0][0]) !=
761 reinterpret_cast<const void *>(&this->mat[0][0])) ||
762 /* Make sure assignment won't overwrite the source. OtherSrc* is the source. */
763 ((OtherSrcStartCol > SrcStartCol) || (OtherSrcStartCol + NumCol <= SrcStartCol) ||
764 (OtherSrcStartRow > SrcStartRow + NumRow) ||
765 (OtherSrcStartRow + NumRow <= SrcStartRow)),
766 "Operation is undefined if views overlap.");
767 unroll<NumCol>([&](auto i) { (*this)[i] = other[i]; });
768 return *this;
769 }
770
772 {
773 *this = other.view();
774 return *this;
775 }
776
779 template<int OtherSrcNumCol,
780 int OtherSrcNumRow,
781 int OtherSrcStartCol,
782 int OtherSrcStartRow,
783 int OtherSrcAlignment>
785 NumCol,
786 NumRow,
787 OtherSrcNumCol,
788 OtherSrcNumRow,
789 OtherSrcStartCol,
790 OtherSrcStartRow,
791 OtherSrcAlignment> &b)
792 {
793 unroll<NumCol>([&](auto i) { (*this)[i] += b[i]; });
794 return *this;
795 }
796
798 {
799 return *this += b.view();
800 }
801
803 {
804 unroll<NumCol>([&](auto i) { (*this)[i] += b; });
805 return *this;
806 }
807
808 template<int OtherSrcNumCol,
809 int OtherSrcNumRow,
810 int OtherSrcStartCol,
811 int OtherSrcStartRow,
812 int OtherSrcAlignment>
814 NumCol,
815 NumRow,
816 OtherSrcNumCol,
817 OtherSrcNumRow,
818 OtherSrcStartCol,
819 OtherSrcStartRow,
820 OtherSrcAlignment> &b)
821 {
822 unroll<NumCol>([&](auto i) { (*this)[i] -= b[i]; });
823 return *this;
824 }
825
827 {
828 return *this -= b.view();
829 }
830
832 {
833 unroll<NumCol>([&](auto i) { (*this)[i] -= b; });
834 return *this;
835 }
836
838 template<int OtherSrcNumCol,
839 int OtherSrcNumRow,
840 int OtherSrcStartCol,
841 int OtherSrcStartRow,
842 int OtherSrcAlignment>
844 NumCol,
845 NumRow,
846 OtherSrcNumCol,
847 OtherSrcNumRow,
848 OtherSrcStartCol,
849 OtherSrcStartRow,
850 OtherSrcAlignment> &b)
851 {
852 *this = *static_cast<MatViewT *>(this) * b;
853 return *this;
854 }
855
857 {
858 return *this *= b.view();
859 }
860
863 {
864 unroll<NumCol>([&](auto i) { (*this)[i] *= b; });
865 return *this;
866 }
867
871 {
872 /* This is the reference implementation.
873 * Might be overloaded with vectorized / optimized code. */
874 col_type result(0);
875 unroll<NumCol>([&](auto c) { result += b[c] * a[c]; });
876 return result;
877 }
878
881 {
882 /* This is the reference implementation.
883 * Might be overloaded with vectorized / optimized code. */
884 row_type result(0);
885 unroll<NumCol>([&](auto c) { unroll<NumRow>([&](auto r) { result[c] += b[c][r] * a[r]; }); });
886 return result;
887 }
888};
889
890namespace detail {
891
893template<typename T,
894 int A_NumCol,
895 int A_NumRow,
896 int B_NumCol,
897 int B_NumRow,
898 typename MatA,
899 typename MatB>
901{
902 static_assert(A_NumCol == B_NumRow);
903 /* This is the reference implementation.
904 * Might be overloaded with vectorized / optimized code. */
906 unroll<B_NumCol>([&](auto j) {
907 unroll<A_NumRow>([&](auto i) {
908 /* Same as dot product, but avoid dependency on vector math. */
909 unroll<A_NumCol>([&](auto k) { result[j][i] += a[k][i] * b[j][k]; });
910 });
911 });
912 return result;
913}
914
915} // namespace detail
916
917template<typename T, int A_NumCol, int A_NumRow, int B_NumCol, int B_NumRow>
920{
921 return detail::matrix_mul_impl<T, A_NumCol, A_NumRow, B_NumCol, B_NumRow>(a, b);
922}
923
924template<typename T,
925 int A_NumCol,
926 int A_NumRow,
927 int A_SrcNumCol,
928 int A_SrcNumRow,
929 int A_SrcStartCol,
930 int A_SrcStartRow,
931 int A_SrcAlignment,
932 int B_NumCol,
933 int B_NumRow,
934 int B_SrcNumCol,
935 int B_SrcNumRow,
936 int B_SrcStartCol,
937 int B_SrcStartRow,
938 int B_SrcAlignment>
940 A_NumCol,
941 A_NumRow,
942 A_SrcNumCol,
943 A_SrcNumRow,
944 A_SrcStartCol,
945 A_SrcStartRow,
946 A_SrcAlignment> &a,
947 const MatView<T,
948 B_NumCol,
949 B_NumRow,
950 B_SrcNumCol,
951 B_SrcNumRow,
952 B_SrcStartCol,
953 B_SrcStartRow,
954 B_SrcAlignment> &b)
955{
956 return detail::matrix_mul_impl<T, A_NumCol, A_NumRow, B_NumCol, B_NumRow>(a, b);
957}
958template<typename T,
959 int A_NumCol,
960 int A_NumRow,
961 int A_SrcNumCol,
962 int A_SrcNumRow,
963 int A_SrcStartCol,
964 int A_SrcStartRow,
965 int A_SrcAlignment,
966 int B_NumCol,
967 int B_NumRow>
969 A_NumCol,
970 A_NumRow,
971 A_SrcNumCol,
972 A_SrcNumRow,
973 A_SrcStartCol,
974 A_SrcStartRow,
975 A_SrcAlignment> &a,
977{
978 return detail::matrix_mul_impl<T, A_NumCol, A_NumRow, B_NumCol, B_NumRow>(a, b);
979}
980
981template<typename T,
982 int A_NumCol,
983 int A_NumRow,
984 int B_NumCol,
985 int B_NumRow,
986 int B_SrcNumCol,
987 int B_SrcNumRow,
988 int B_SrcStartCol,
989 int B_SrcStartRow,
990 int B_SrcAlignment>
992 const MatView<T,
993 B_NumCol,
994 B_NumRow,
995 B_SrcNumCol,
996 B_SrcNumRow,
997 B_SrcStartCol,
998 B_SrcStartRow,
999 B_SrcAlignment> &b)
1000{
1001 return detail::matrix_mul_impl<T, A_NumCol, A_NumRow, B_NumCol, B_NumRow>(a, b);
1002}
1003
1013
1014/* These types are reserved to wrap C matrices without copy. Note the un-alignment. */
1015/* TODO: It would be preferable to align all C matrices inside DNA structs. */
1016using float4x4_view = MatView<float, 4, 4, 4, 4, 0, 0, alignof(float)>;
1017using float4x4_mutableview = MutableMatView<float, 4, 4, 4, 4, 0, 0, alignof(float)>;
1018
1028
1029/* Specialization for SSE optimization. */
1030template<> float4x4 operator*(const float4x4 &a, const float4x4 &b);
1031template<> float3x3 operator*(const float3x3 &a, const float3x3 &b);
1032
1033extern template float2x2 operator*(const float2x2 &a, const float2x2 &b);
1034extern template double2x2 operator*(const double2x2 &a, const double2x2 &b);
1035extern template double3x3 operator*(const double3x3 &a, const double3x3 &b);
1036extern template double4x4 operator*(const double4x4 &a, const double4x4 &b);
1037
1038} // namespace blender
#define BLI_STATIC_ASSERT(a, msg)
Definition BLI_assert.h:87
#define BLI_assert(a)
Definition BLI_assert.h:50
#define BLI_assert_msg(a, msg)
Definition BLI_assert.h:57
unsigned int U
Definition btGjkEpa3.h:78
local_group_size(16, 16) .push_constant(Type b
draw_view in_light_buf[] float
ccl_device_inline float2 operator*(const float2 a, const float2 b)
Definition math_float2.h:30
#define T
MatBase< T, B_NumCol, A_NumRow > matrix_mul_impl(const MatA &a, const MatB &b)
std::conditional_t< sizeof(T)==sizeof(uint8_t), uint8_t, std::conditional_t< sizeof(T)==sizeof(uint16_t), uint16_t, std::conditional_t< sizeof(T)==sizeof(uint32_t), uint32_t, std::conditional_t< sizeof(T)==sizeof(uint64_t), uint64_t, void > > > > as_uint_type
unsigned __int64 uint64_t
Definition stdint.h:90
friend MatBase operator-(const MatBase &a)
static MatBase diagonal(T value)
friend MatBase operator*(const MatBase &a, T b)
friend MatBase operator-(T a, const MatBase &b)
MatBase & operator+=(const MatBase &b)
friend MatBase operator+(T a, const MatBase &b)
MatBase(col_type _x, col_type _y, col_type _z)
MatBase(const MatBase< U, NumRow, NumCol > &vec)
MatBase(col_type _x, col_type _y, col_type _z, col_type _w)
MatBase(const T(*ptr)[NumCol])
col_type & operator[](int index)
MatBase & operator-=(const MatBase &b)
T[NumCol][NumRow] c_style_mat
friend col_type operator*(const MatBase &a, const row_type &b)
MutableMatView< T, ViewNumCol, ViewNumRow, NumCol, NumRow, SrcStartCol, SrcStartRow, Alignment > view()
friend MatBase operator+(const MatBase &a, T b)
const vec3_type & z_axis() const
friend MatBase operator*(T a, const MatBase &b)
const vec3_type & x_axis() const
friend MatBase operator-(const MatBase &a, T b)
const col_type & operator[](int index) const
friend row_type operator*(const col_type &a, const MatBase &b)
friend MatBase operator+(const MatBase &a, const MatBase &b)
MatBase & operator*=(const MatBase &b)
friend std::ostream & operator<<(std::ostream &stream, const MatBase &mat)
MatBase()=default
const c_style_mat & ptr() const
friend MatBase operator-(const MatBase &a, const MatBase &b)
const vec3_type & y_axis() const
MatBase(const MatBase< U, OtherNumCol, OtherNumRow > &other)
friend bool operator!=(const MatBase &a, const MatBase &b)
const MatView< T, ViewNumCol, ViewNumRow, NumCol, NumRow, SrcStartCol, SrcStartRow, Alignment > view() const
friend bool operator==(const MatBase &a, const MatBase &b)
static MatBase all(T value)
const loc_type & location() const
const T * base_ptr() const
static MatBase identity()
MatBase(col_type _x, col_type _y)
friend MatT operator-(const MatView &a, const MatView< T, NumCol, NumRow, OtherSrcNumCol, OtherSrcNumRow, OtherSrcStartCol, OtherSrcStartRow, OtherSrcAlignment > &b)
const col_type & operator[](int index) const
friend MatT operator-(const MatT &a, const MatView &b)
MatT operator*(const MatT &b) const
MatView(const SrcMatT &src)
friend MatT operator*(const MatView &a, T b)
friend bool operator!=(const MatView &a, const MatView &b)
friend MatT operator-(const MatView &a, T b)
friend MatT operator-(const MatView &a)
friend std::ostream & operator<<(std::ostream &stream, const MatView &mat)
friend col_type operator*(const MatView &a, const row_type &b)
friend bool operator==(const MatView &a, const MatView &b)
friend MatT operator-(const MatView< T, NumCol, NumRow, OtherSrcNumCol, OtherSrcNumRow, OtherSrcStartCol, OtherSrcStartRow, OtherSrcAlignment > &a, const MatView &b)
friend row_type operator*(const col_type &a, const MatView &b)
friend MatT operator+(const MatView &a, T b)
friend MatT operator+(T a, const MatView &b)
friend MatT operator-(const MatView &a, const MatT &b)
MatView(const float(*src)[SrcNumRow])
friend MatT operator*(T a, const MatView &b)
friend MatView operator-(T a, const MatView &b)
friend col_type operator*(MutableMatView &a, const row_type &b)
friend row_type operator*(const col_type &a, MutableMatView &b)
MutableMatView & operator*=(const MatView< T, NumCol, NumRow, OtherSrcNumCol, OtherSrcNumRow, OtherSrcStartCol, OtherSrcStartRow, OtherSrcAlignment > &b)
MutableMatView & operator+=(const MatView< T, NumCol, NumRow, OtherSrcNumCol, OtherSrcNumRow, OtherSrcStartCol, OtherSrcStartRow, OtherSrcAlignment > &b)
col_type & operator[](int index)
MutableMatView & operator-=(T b)
MutableMatView & operator*=(const MatT &b)
MutableMatView & operator=(const MatView< T, NumCol, NumRow, OtherSrcNumCol, OtherSrcNumRow, OtherSrcStartCol, OtherSrcStartRow, OtherSrcAlignment > &other)
MutableMatView(float src[SrcNumCol][SrcNumRow])
MutableMatView & operator*=(T b)
MutableMatView & operator+=(const MatT &b)
MutableMatView & operator=(const MatT &other)
MutableMatView & operator+=(T b)
MutableMatView & operator-=(const MatT &b)
MutableMatView & operator-=(const MatView< T, NumCol, NumRow, OtherSrcNumCol, OtherSrcNumRow, OtherSrcStartCol, OtherSrcStartRow, OtherSrcAlignment > &b)
PointerRNA * ptr
Definition wm_files.cc:4126