Loading...
Searching...
No Matches
mat.h
Go to the documentation of this file.
1#ifndef _BBM_MAT_H_
2#define _BBM_MAT_H_
3
4#include <ostream>
5
6#include "core/vec.h"
8
9/************************************************************************/
10/*! \file matrix.h
11
12 \brief Defines mat2d and mat3d on top of vec2d and vec3d
13
14************************************************************************/
15
16namespace bbm {
17
18 /*** Implementation details for matrices ***/
19 namespace detail {
20
21 template<typename Vec, size_t N>
22 struct mat
23 {
24 using value = value_t<Vec>;
25
26 //! \brief Default constructor
27 inline mat(void) : _col() {};
28
29 //! \brief Set the diagonal to val
30 inline mat(value&& val)
31 {
32 for(size_t i=0; i != N; ++i)
33 {
34 _col[i] = 0;
35 _col[i][i] = val;
36 }
37 }
38
39 //! brief Set each column
40 template<typename... V> requires (sizeof...(V) == N)
41 inline mat(V&&... col) : _col({(std::forward<V>(col))...}) {};
42
43 //! \brief Copy constructor
44 inline mat(const mat& src) : _col(src._col) {}
45
46 //! @{ \name Lookup operator
47 decltype(auto) operator()(size_t row, size_t col) const { return _col[col][row]; }
48 decltype(auto) operator()(size_t row, size_t col) { return _col[col][row]; }
49
50 decltype(auto) col(size_t col) const { return _col[col]; }
51 Vec row(size_t row) const
52 {
53 Vec result;
54 for(size_t i=0; i != N; ++i)
55 result[i] = _col[i][row];
56 return result;
57 }
58 //! @}
59
60 //! @{ Matrix Methods
61 friend mat transpose(const mat& m)
62 {
63 mat result;
64 for(size_t row=0; row != N; ++row)
65 for(size_t col=0; col != N; ++col)
66 result(col,row) = m(row,col);
67 return result;
68 }
69 //! @}
70
71 //! \brief Print to ostream
72 friend std::ostream& operator<<(std::ostream& s, const mat& m)
73 {
74 s << "[";
75 for(size_t i=0; i != N; ++i)
76 {
77 if(i != 0) s << ", ";
78 s << m.row(i);
79 }
80 s << "]";
81 return s;
82 }
83
84 //! @{ \name Math Operators
85 inline mat operator-(void) const { return apply_op(std::negate<>()); }
86
87 inline mat operator+(const mat& m) const { return apply_op(std::plus<>(), m._col); }
88 inline mat operator-(const mat& m) const { return apply_op(std::minus<>(), m._col); }
89
90 inline mat& operator+=(const mat& m) { return apply_op_inplace( [](auto& r, auto& m) { r += m; }, m); }
91 inline mat& operator-=(const mat& m) { return apply_op_inplace( [](auto& r, auto& m) { r -= m; }, m); }
92
93 inline mat operator+(const value& v) const { return apply_op(std::plus<>(), v); }
94 inline mat operator-(const value& v) const { return apply_op(std::minus<>(), v); }
95 inline mat operator*(const value& v) const { return apply_op(std::multiplies<>(), v); }
96 inline mat operator/(const value& v) const { return apply_op(std::divides<>(), v); }
97
98 inline mat& operator+=(value&& v) { return apply_op_inplace([](auto& r, auto& v) { r+= v; }, v); }
99 inline mat& operator-=(value&& v) { return apply_op_inplace([](auto& r, auto& v) { r-= v; }, v); }
100 inline mat& operator*=(value&& v) { return apply_op_inplace([](auto& r, auto& v) { r*= v; }, v); }
101 inline mat& operator/=(value&& v) { return apply_op_inplace([](auto& r, auto& v) { r/= v; }, v); }
102
103 friend inline constexpr mat operator+(const value& v, const mat& m) { return (m+v); }
104 friend inline constexpr mat operator-(const value& v, const mat& m) { return (-m + v); }
105 friend inline constexpr mat operator*(const value& v, const mat& m) { return (m*v); }
106
107 inline Vec operator*(const Vec& v) const
108 {
109 Vec result;
110 for(size_t r=0; r != N; ++r)
111 {
112 auto row = this->row(r);
113 result[r] = dot(row, v);
114 }
115 return result;
116 }
117
118 inline mat operator*(const mat& m) const
119 {
120 mat result;
121 for(size_t r=0; r != N; ++r)
122 {
123 auto row = this->row(r);
124 for(size_t c=0; c != N; ++c)
125 result(r, c) = dot(row, m.col(c));
126 }
127 return result;
128 }
129
130 inline mat& operator*=(const mat& m)
131 {
132 *this = *this * m;
133 return *this;
134 }
135 //! @}
136
137 private:
138 //! \brief Helper method for applying an operation to a matrix
139 template<typename... T, typename OP>
140 inline auto apply_op(const OP& op, T&&... t) const
141 {
142 mat result;
143 multirange_for([&](auto& r, auto&... m) { r = op(m...); }, result._col, _col, t...);
144 return result;
145 }
146
147 //! \brief Helper method for applying an operation to a matrix in place
148 template<typename... T, typename OP>
149 inline auto& apply_op_inplace(const OP& op, T&&... t)
150 {
151 multirange_for([&](auto&... m) { op(m...); }, _col, t...);
152 return *this;
153 }
154
155
156 /////////////////
157 // Data Members
158 /////////////////
159 std::array<Vec, N> _col;
160 };
161
162 } // end detail namespace
163
164 //! \brief create an identity matrix
165 template<typename M>
166 inline constexpr M identity(void) { return M(1); }
167
168 //! \brief Bring 'transpose' in the bbm namespace
169 template<typename M>
170 inline constexpr M transpose(const M& m) { return transpose(m); }
171
172 //! \brief 2D matrix
173 template<typename T>
174 using mat2d = bbm::detail::mat<vec2d<T>, 2>;
175
176 //! \brief 3D matrix
177 template<typename T>
178 using mat3d = bbm::detail::mat<vec3d<T>, 3>;
179
180} // end bbm namespace
181
182#endif /* _BBM_MAT_H_ */
Defines additional helper methods for vectors.
ranged for loop over multiple containers at once
auto dot(const T &a, const T &b)
Definition: horizontal.h:17
constexpr decltype(auto) r(bbm::color< T > &c)
Definition: color.h:18
constexpr decltype(auto) v(bbm::vec2d< T > &v)
Definition: vec.h:40
Definition: aggregatebsdf.h:29
constexpr M transpose(const M &m)
Bring 'transpose' in the bbm namespace.
Definition: mat.h:170
auto operator/(const vector< T > &v, const U &u)
Definition: vector_util.h:273
constexpr FLAGNAME operator+(FLAGNAME a, FLAGNAME b)
Conact two flags.
Definition: flags.h:40
bbm::detail::mat< vec3d< T >, 3 > mat3d
3D matrix
Definition: mat.h:178
constexpr FLAGNAME & operator+=(FLAGNAME &a, FLAGNAME b)
Update 'a' with a+b.
Definition: flags.h:84
auto & operator*=(vector< T > &v, const U &u)
Definition: vector_util.h:267
bbm::detail::mat< vec2d< T >, 2 > mat2d
2D matrix
Definition: mat.h:174
auto operator*(const vector< T > &v, const U &u)
Definition: vector_util.h:268
auto & operator/=(vector< T > &v, const U &u)
Definition: vector_util.h:272
void multirange_for(FUNC &&func, Ts &&... containers)
ranged for loop over multiple containers at once
Definition: multirange_for.h:43
std::ostream & operator<<(std::ostream &s, const BSDF &bsdf)
Definition: bsdf_base.h:138
constexpr M identity(void)
create an identity matrix
Definition: mat.h:166
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20
auto & operator-=(vector< T > &v, const U &u)
Definition: vector_util.h:263
auto operator-(const vector< T > &v, const U &u)
Definition: vector_util.h:264