File include/math/matrix/base.h changed (mode: 100644) (index 6e2c3ac..ba4ae77) |
3 |
3 |
#include "../vector/base.h" |
#include "../vector/base.h" |
4 |
4 |
#include <cstddef> |
#include <cstddef> |
5 |
5 |
#include <type_traits> |
#include <type_traits> |
|
6 |
|
#include <array> |
6 |
7 |
|
|
7 |
8 |
#define T_NUMERIC template<typename numeric_t> constexpr inline |
#define T_NUMERIC template<typename numeric_t> constexpr inline |
8 |
9 |
#define T_OTHER template<typename other_t> constexpr inline |
#define T_OTHER template<typename other_t> constexpr inline |
9 |
|
#define T_OTHER_OTHER template<unsigned int other_size, unsigned int other_vector_size, typename other_t> constexpr inline |
|
|
10 |
|
|
10 |
11 |
namespace math |
namespace math |
11 |
12 |
{ |
{ |
12 |
|
template<unsigned int size, unsigned int vector_size, typename type> |
|
13 |
|
struct matrix |
|
14 |
|
{ |
|
15 |
|
using vector = vector<vector_size, type>; |
|
16 |
|
|
|
17 |
|
vector _[size]; |
|
18 |
|
|
|
19 |
|
T_OTHER_OTHER static matrix from(const matrix<other_size, other_vector_size, other_t> &); |
|
20 |
|
|
|
21 |
|
T_OTHER operator matrix<size, vector_size, other_t> (); |
|
22 |
|
|
|
23 |
|
|
|
24 |
|
constexpr inline bool operator==(const matrix &); |
|
25 |
|
constexpr inline bool operator!=(const matrix &); |
|
26 |
|
|
|
27 |
|
T_NUMERIC vector& operator[](numeric_t i); |
|
28 |
|
T_NUMERIC vector operator[](numeric_t i) const; |
|
29 |
|
|
|
30 |
|
// T_OTHER matrix& operator += (const matrix<size, vector_size, other_t>&); |
|
31 |
|
// T_OTHER matrix& operator -= (const matrix<size, vector_size, other_t>&); |
|
32 |
|
|
|
33 |
|
template<unsigned int other_size, unsigned int other_vector_size, typename other_t> constexpr inline |
|
34 |
|
matrix& operator *= (const matrix<other_size, other_vector_size, other_t>&); |
|
35 |
|
|
|
36 |
|
template<unsigned int other_size, unsigned int other_vector_size, typename other_t> constexpr inline |
|
37 |
|
matrix<size, other_vector_size, type> operator *(const matrix<other_size, other_vector_size, other_t>&) const; |
|
38 |
|
|
|
39 |
|
template<typename other_t> constexpr inline |
|
40 |
|
vector operator *(const math::vector<size, other_t>&) const; |
|
41 |
|
|
|
42 |
|
|
|
43 |
|
// T_OTHER matrix& operator /= (const matrix<size, vector_size, other_t>&); |
|
44 |
|
// T_OTHER matrix operator + (const matrix<size, vector_size, other_t>&) const; |
|
45 |
|
// T_OTHER matrix operator - (const matrix<size, vector_size, other_t>&) const; |
|
46 |
|
// T_OTHER matrix operator / (const matrix<size, vector_size, other_t>&) const; |
|
47 |
|
|
|
48 |
|
T_NUMERIC matrix& operator += (const numeric_t&); |
|
49 |
|
T_NUMERIC matrix& operator -= (const numeric_t&); |
|
50 |
|
// T_NUMERIC matrix& operator *= (const numeric_t&); |
|
51 |
|
T_NUMERIC matrix& operator /= (const numeric_t&); |
|
52 |
|
T_NUMERIC matrix operator + (const numeric_t&) const; |
|
53 |
|
T_NUMERIC matrix operator - (const numeric_t&) const; |
|
54 |
|
// T_NUMERIC matrix operator * (const numeric_t&) const; |
|
55 |
|
T_NUMERIC matrix operator / (const numeric_t&) const; |
|
56 |
|
}; |
|
57 |
|
|
|
58 |
|
/* template<typename type> |
|
59 |
|
struct matrix<4,4, type> |
|
60 |
|
{ |
|
61 |
|
template<typename other_t> inline |
|
62 |
|
matrix<4, 4, type> operator * (const matrix<4, 4, other_t>& other) const; |
|
63 |
|
};*/ |
|
|
13 |
|
template<int size, int vector_size, typename type> |
|
14 |
|
struct matrix //: vector<size, vector<vector_size, type>> |
|
15 |
|
{ |
|
16 |
|
using vector = vector<vector_size, type>; |
|
17 |
|
//TODO make initialization without excess braces |
|
18 |
|
vector _[size]; |
|
19 |
|
|
|
20 |
|
template<int other_size, int other_vector_size, typename other_t> |
|
21 |
|
[[nodiscard]] constexpr inline static matrix |
|
22 |
|
from(const matrix<other_size, other_vector_size, other_t> &); |
|
23 |
|
|
|
24 |
|
T_OTHER operator matrix<size, vector_size, other_t> () { |
|
25 |
|
return matrix<size, vector_size, other_t>::from(*this); |
|
26 |
|
} |
|
27 |
|
|
|
28 |
|
[[nodiscard]] constexpr bool operator==(const matrix &other) { |
|
29 |
|
return memcmp(this, &other, sizeof(*this)) == 0; |
|
30 |
|
} |
|
31 |
|
constexpr inline bool operator!=(const matrix &m) { return *this != m; } |
|
32 |
|
|
|
33 |
|
T_NUMERIC vector& operator[](numeric_t i) { return _[i]; } |
|
34 |
|
T_NUMERIC vector operator[](numeric_t i) const { return _[i]; } |
|
35 |
|
|
|
36 |
|
template<int other_size, int other_vector_size, typename other_t> |
|
37 |
|
constexpr inline matrix& |
|
38 |
|
operator *= (const matrix<other_size, other_vector_size, other_t>&); |
|
39 |
|
|
|
40 |
|
template<int other_size, int other_vector_size, typename other_t> |
|
41 |
|
constexpr inline matrix<size, other_vector_size, type> |
|
42 |
|
operator *(const matrix<other_size, other_vector_size, other_t>&) const; |
|
43 |
|
|
|
44 |
|
template<typename other_t> [[nodiscard]] constexpr inline |
|
45 |
|
vector operator *(const math::vector<size, other_t>&) const; |
|
46 |
|
|
|
47 |
|
T_NUMERIC matrix& operator += (const numeric_t&); |
|
48 |
|
T_NUMERIC matrix& operator -= (const numeric_t&); |
|
49 |
|
T_NUMERIC matrix& operator /= (const numeric_t&); |
|
50 |
|
T_NUMERIC matrix operator + (const numeric_t&n) const {return *this += n;} |
|
51 |
|
T_NUMERIC matrix operator - (const numeric_t&n) const {return *this -= n;} |
|
52 |
|
T_NUMERIC matrix operator / (const numeric_t&n) const {return *this /= n;} |
|
53 |
|
}; |
64 |
54 |
} |
} |
65 |
|
#undef T_OTHER_OTHER |
|
66 |
55 |
#undef T_NUMERIC |
#undef T_NUMERIC |
67 |
56 |
#undef T_OTHER |
#undef T_OTHER |
File include/math/matrix/base.hpp changed (mode: 100644) (index 9bcf3e6..7b3ab1c) |
5 |
5 |
|
|
6 |
6 |
namespace math |
namespace math |
7 |
7 |
{ |
{ |
8 |
|
#define MATR_T template<unsigned int size, unsigned int vector_size, typename type> |
|
9 |
|
#define T_IMPL template<unsigned int size, unsigned int vector_size, typename type> constexpr inline |
|
10 |
|
#define T_OTHER_IMPL template<unsigned int size, unsigned int vector_size, typename type> template<typename other_t> constexpr inline |
|
11 |
|
#define T_OTHER_OTHER_IMP template<unsigned int size, unsigned int vector_size, typename type> \ |
|
12 |
|
template<unsigned int other_size, unsigned int other_vector_size, typename other_t> constexpr inline |
|
13 |
|
#define T_NUMERIC_IMPL template<unsigned int size, unsigned int vector_size, typename type> template<typename numeric_t> constexpr inline |
|
|
8 |
|
#define MATR_T template<int size, int vector_size, typename type> |
|
9 |
|
#define T_OTHER_OTHER_IMP template<int size, int vector_size, typename type> \ |
|
10 |
|
template<int other_size, int other_vector_size, typename other_t> \ |
|
11 |
|
constexpr inline |
|
12 |
|
#define T_NUMERIC_IMPL template<int size, int vector_size, typename type> \ |
|
13 |
|
template<typename numeric_t> constexpr inline |
14 |
14 |
#define MATRIX matrix<size, vector_size, type> |
#define MATRIX matrix<size, vector_size, type> |
15 |
|
#define MATRIX_OTHER matrix<size, vector_size, other_t> |
|
16 |
15 |
#define MATRIX_OTHER_OTHER matrix<other_size, other_vector_size, other_t> |
#define MATRIX_OTHER_OTHER matrix<other_size, other_vector_size, other_t> |
17 |
16 |
|
|
18 |
|
T_OTHER_OTHER_IMP MATRIX MATRIX::from(const MATRIX_OTHER_OTHER &other) |
|
19 |
|
{ |
|
20 |
|
MATRIX m{}; unsigned int i = 0, j = 0; |
|
21 |
|
for (; i < size && i < other_size; ++i) |
|
22 |
|
{ |
|
23 |
|
for (j = 0; j < vector_size && j < other_vector_size; ++j) |
|
24 |
|
m._[i][j] = type(other._[i][j]); |
|
25 |
|
for (; j < vector_size; ++j) |
|
26 |
|
m._[i][j] = type(0); |
|
27 |
|
} |
|
28 |
|
for (; i < size; ++i) |
|
29 |
|
for (; j < vector_size; ++j) |
|
30 |
|
m._[i][j] = type(0); |
|
31 |
|
return m; |
|
32 |
|
} |
|
33 |
|
|
|
34 |
|
T_OTHER_IMPL MATRIX::operator MATRIX_OTHER() |
|
35 |
|
{ |
|
36 |
|
return MATRIX_OTHER::from(*this); |
|
37 |
|
} |
|
38 |
|
|
|
39 |
|
T_IMPL bool MATRIX::operator==(const MATRIX &other) |
|
40 |
|
{ |
|
41 |
|
return memcmp(this, &other, sizeof(*this)) == 0; |
|
42 |
|
} |
|
43 |
|
T_IMPL bool MATRIX::operator!=(const MATRIX &other) |
|
44 |
|
{ |
|
45 |
|
return memcmp(this, &other, sizeof(*this)) != 0; |
|
46 |
|
} |
|
47 |
|
|
|
48 |
|
T_NUMERIC_IMPL typename MATRIX::vector& MATRIX::operator[](numeric_t i) |
|
49 |
|
{ |
|
50 |
|
return _[i]; |
|
51 |
|
} |
|
52 |
|
T_NUMERIC_IMPL typename MATRIX::vector MATRIX::operator[](numeric_t i) const |
|
53 |
|
{ |
|
54 |
|
return _[i]; |
|
55 |
|
} |
|
56 |
|
/* |
|
57 |
|
T_OTHER_IMPL MATRIX& MATRIX::operator += (const MATRIX_OTHER& other) |
|
58 |
|
{ |
|
59 |
|
for (unsigned int i = 0; i < size; ++i) |
|
60 |
|
_[i] += other[i]; |
|
61 |
|
return *this; |
|
62 |
|
} |
|
63 |
|
T_OTHER_IMPL MATRIX& MATRIX::operator -= (const MATRIX_OTHER& other) |
|
64 |
|
{ |
|
65 |
|
for (unsigned int i = 0; i < size; ++i) |
|
66 |
|
_[i] -= other[i]; |
|
67 |
|
return *this; |
|
68 |
|
}*/ |
|
69 |
|
MATR_T template<unsigned int other_size, unsigned int other_vector_size, typename other_t> constexpr inline |
|
70 |
|
MATRIX& MATRIX::operator *= (const matrix<other_size, other_vector_size, other_t>& other) |
|
71 |
|
{ |
|
72 |
|
static_assert(other_vector_size == vector_size); |
|
73 |
|
return *this = (*this)*other; |
|
74 |
|
} |
|
75 |
|
/* T_OTHER_IMPL MATRIX& MATRIX::operator /= (const MATRIX_OTHER& other) |
|
76 |
|
{ |
|
77 |
|
for (int i = 0; i < size; ++i) |
|
78 |
|
_[i] /= other[i]; |
|
79 |
|
return *this; |
|
80 |
|
} |
|
81 |
|
T_OTHER_IMPL MATRIX MATRIX::operator + (const MATRIX_OTHER& other) const |
|
82 |
|
{ |
|
83 |
|
return MATRIX {*this}.operator += (other); |
|
84 |
|
} |
|
85 |
|
T_OTHER_IMPL MATRIX MATRIX::operator - (const MATRIX_OTHER& other) const |
|
86 |
|
{ |
|
87 |
|
return MATRIX {*this}.operator -= (other); |
|
88 |
|
} |
|
89 |
|
T_OTHER_IMPL MATRIX MATRIX::operator / (const MATRIX_OTHER& other) const |
|
90 |
|
{ |
|
91 |
|
return MATRIX {*this}.operator /= (other); |
|
92 |
|
}*/ |
|
93 |
|
MATR_T template<unsigned int other_size, unsigned int other_vector_size, typename other_t> constexpr inline |
|
94 |
|
matrix<size, other_vector_size, type> MATRIX::operator * (const matrix<other_size, other_vector_size, other_t>& other) const |
|
95 |
|
{ |
|
96 |
|
static_assert(other_size == vector_size); |
|
97 |
|
|
|
98 |
|
matrix<size, other_vector_size, type> m {}; |
|
99 |
|
|
|
100 |
|
/*for(unsigned int i = 0; i < size; i++) |
|
101 |
|
for(unsigned int k = 0; k < vector_size; k++) |
|
102 |
|
for(unsigned int j = 0; j < other_vector_size; j++) |
|
103 |
|
m._[i][j] += _[i][k] * other._[k][j];*/ |
|
104 |
|
|
|
105 |
|
for (unsigned int i = 0; i < vector_size; ++i) |
|
106 |
|
for (unsigned int j = 0; j < size; ++j) |
|
107 |
|
m[j] += _[i] * other[j][i]; |
|
108 |
|
|
|
109 |
|
|
|
110 |
|
return m; |
|
111 |
|
} |
|
|
17 |
|
T_OTHER_OTHER_IMP MATRIX MATRIX::from(const MATRIX_OTHER_OTHER &other) { |
|
18 |
|
MATRIX m{}; int i = 0, j = 0; |
|
19 |
|
for (; i < size && i < other_size; ++i) { |
|
20 |
|
for (j = 0; j < vector_size && j < other_vector_size; ++j) |
|
21 |
|
m._[i][j] = type(other._[i][j]); |
|
22 |
|
for (; j < vector_size; ++j) |
|
23 |
|
m._[i][j] = type(0); |
|
24 |
|
} |
|
25 |
|
for (; i < size; ++i) |
|
26 |
|
for (; j < vector_size; ++j) |
|
27 |
|
m._[i][j] = type(0); |
|
28 |
|
return m; |
|
29 |
|
} |
|
30 |
|
|
|
31 |
|
MATR_T template<int other_size, int other_vector_size, typename other_t> |
|
32 |
|
[[nodiscard]] constexpr inline MATRIX& |
|
33 |
|
MATRIX::operator*=(const matrix<other_size, other_vector_size, other_t>& m) { |
|
34 |
|
static_assert(other_vector_size == vector_size); |
|
35 |
|
return *this = (*this) * m; |
|
36 |
|
} |
|
37 |
|
MATR_T template<int other_size, int other_vector_size, typename other_t> |
|
38 |
|
[[nodiscard]] constexpr inline matrix<size, other_vector_size, type> |
|
39 |
|
MATRIX::operator*(const matrix<other_size, other_vector_size, other_t>& other) |
|
40 |
|
const { |
|
41 |
|
static_assert(other_size == vector_size); |
|
42 |
|
matrix<size, other_vector_size, type> m {}; |
|
43 |
|
for(int i = 0; i < size; i++) |
|
44 |
|
for(int k = 0; k < vector_size; k++) |
|
45 |
|
for(int j = 0; j < other_vector_size; j++) |
|
46 |
|
m._[i][j] += _[i][k] * other._[k][j]; |
|
47 |
|
return m; |
|
48 |
|
} |
112 |
49 |
/*template<typename type> template<typename other_t> inline |
/*template<typename type> template<typename other_t> inline |
113 |
50 |
matrix<4, 4, type> matrix<4, 4, type>::operator * (const matrix<4, 4, other_t>& other) const |
matrix<4, 4, type> matrix<4, 4, type>::operator * (const matrix<4, 4, other_t>& other) const |
114 |
51 |
{ |
{ |
|
... |
... |
namespace math |
118 |
55 |
_[0] * other[3][0] + _[1] * other[3][1] + _[2] * other[3][2] + _[3] * other[3][3] }; |
_[0] * other[3][0] + _[1] * other[3][1] + _[2] * other[3][2] + _[3] * other[3][3] }; |
119 |
56 |
}*/ |
}*/ |
120 |
57 |
|
|
121 |
|
MATR_T template<typename other_t> constexpr inline |
|
122 |
|
typename MATRIX::vector MATRIX::operator *(const math::vector<size, other_t>& vec) const |
|
123 |
|
{ |
|
124 |
|
static_assert (size == vector_size); |
|
125 |
|
|
|
126 |
|
MATRIX::vector result{}; |
|
127 |
|
for(unsigned int i = 0; i < size; i++) |
|
128 |
|
for(unsigned int k = 0; k < vector_size; k++) |
|
129 |
|
result._[i] += _[i][k] * vec._[k]; |
|
130 |
|
|
|
131 |
|
return result; |
|
132 |
|
} |
|
133 |
|
|
|
134 |
|
T_NUMERIC_IMPL MATRIX& MATRIX::operator += (const numeric_t& value) |
|
135 |
|
{ |
|
136 |
|
for (unsigned int i = 0; i < size; ++i) |
|
137 |
|
_[i] += value; |
|
138 |
|
return *this; |
|
139 |
|
} |
|
140 |
|
T_NUMERIC_IMPL MATRIX& MATRIX::operator -= (const numeric_t& value) |
|
141 |
|
{ |
|
142 |
|
for (unsigned int i = 0; i < size; ++i) |
|
143 |
|
_[i] -= value; |
|
144 |
|
return *this; |
|
145 |
|
}/* |
|
146 |
|
T_NUMERIC_IMPL MATRIX& MATRIX::operator *= (const numeric_t& value) |
|
147 |
|
{ |
|
148 |
|
for (unsigned int i = 0; i < size; ++i) |
|
149 |
|
_[i] *= value; |
|
150 |
|
return *this; |
|
151 |
|
}*/ |
|
152 |
|
T_NUMERIC_IMPL MATRIX& MATRIX::operator /= (const numeric_t& value) |
|
153 |
|
{ |
|
154 |
|
for (unsigned int i = 0; i < size; ++i) |
|
155 |
|
_[i] /= value; |
|
156 |
|
return *this; |
|
157 |
|
} |
|
158 |
|
T_NUMERIC_IMPL MATRIX MATRIX::operator + (const numeric_t& value) const |
|
159 |
|
{ |
|
160 |
|
return MATRIX {*this}.operator += (value); |
|
161 |
|
} |
|
162 |
|
T_NUMERIC_IMPL MATRIX MATRIX::operator - (const numeric_t& value) const |
|
163 |
|
{ |
|
164 |
|
return MATRIX {*this}.operator -= (value); |
|
165 |
|
} |
|
166 |
|
T_NUMERIC_IMPL MATRIX MATRIX::operator / (const numeric_t& value) const |
|
167 |
|
{ |
|
168 |
|
return MATRIX {*this}.operator /= (value); |
|
169 |
|
}/* |
|
170 |
|
T_NUMERIC_IMPL MATRIX MATRIX::operator * (const numeric_t& value) const |
|
171 |
|
{ |
|
172 |
|
return MATRIX {*this}.operator *= (value); |
|
173 |
|
}*/ |
|
|
58 |
|
MATR_T template<typename other_t> |
|
59 |
|
[[nodiscard]] constexpr inline typename MATRIX::vector |
|
60 |
|
MATRIX::operator *(const math::vector<size, other_t>& vec) const { |
|
61 |
|
static_assert (size == vector_size); |
|
62 |
|
MATRIX::vector result{}; |
|
63 |
|
for(int i = 0; i < size; i++) |
|
64 |
|
for(int k = 0; k < vector_size; k++) |
|
65 |
|
result[i] += (*this)[i][k] * vec._[k]; |
|
66 |
|
return result; |
|
67 |
|
} |
|
68 |
|
T_NUMERIC_IMPL MATRIX& MATRIX::operator += (const numeric_t& value) { |
|
69 |
|
for (int i = 0; i < size; ++i) |
|
70 |
|
(*this)[i] += value; |
|
71 |
|
return *this; |
|
72 |
|
} |
|
73 |
|
T_NUMERIC_IMPL MATRIX& MATRIX::operator -= (const numeric_t& value) { |
|
74 |
|
for (int i = 0; i < size; ++i) |
|
75 |
|
(*this)[i] -= value; |
|
76 |
|
return *this; |
|
77 |
|
} |
|
78 |
|
T_NUMERIC_IMPL MATRIX& MATRIX::operator /= (const numeric_t& value) { |
|
79 |
|
for (int i = 0; i < size; ++i) |
|
80 |
|
(*this)[i] /= value; |
|
81 |
|
return *this; |
|
82 |
|
} |
174 |
83 |
#undef MATRIX_OTHER_OTHER |
#undef MATRIX_OTHER_OTHER |
175 |
84 |
#undef T_OTHER_OTHER_IMP |
#undef T_OTHER_OTHER_IMP |
176 |
|
#undef T_IMPL |
|
177 |
|
#undef T_OTHER_IMPL |
|
178 |
85 |
#undef T_NUMERIC_IMPL |
#undef T_NUMERIC_IMPL |
179 |
86 |
#undef MATRIX |
#undef MATRIX |
180 |
87 |
#undef MATRIX_OTHER |
#undef MATRIX_OTHER |
File include/math/matrix/matrix_functions.hpp changed (mode: 100644) (index 3172596..e44c862) |
1 |
1 |
#pragma once |
#pragma once |
2 |
2 |
|
|
3 |
|
#include "matrix_functions.h" |
|
|
3 |
|
#include "base.h" |
4 |
4 |
#include "../constants.h" |
#include "../constants.h" |
5 |
5 |
#include "../vector/vector_functions.h" |
#include "../vector/vector_functions.h" |
6 |
6 |
|
|
|
8 |
8 |
|
|
9 |
9 |
namespace math |
namespace math |
10 |
10 |
{ |
{ |
11 |
|
#define T_IMPL template<typename T> constexpr inline |
|
12 |
|
#define MATRIX4 matrix<4, 4, T> |
|
13 |
|
#define VECTOR3 vector<3, T> |
|
|
11 |
|
#define T_IMPL template<typename T> [[nodiscard]] constexpr inline |
|
12 |
|
#define MATRIX(n) matrix<n, n, T> |
|
13 |
|
#define VECTOR(n) vector<n, T> |
|
14 |
|
#define VEC_ARG(n) const vector<n, T>& |
14 |
15 |
#define MATRIXN_IMP \ |
#define MATRIXN_IMP \ |
15 |
|
template<unsigned int size, typename T> \ |
|
16 |
|
constexpr inline matrix<size, size, T> |
|
|
16 |
|
template<unsigned int size, typename T> [[nodiscard]] constexpr inline \ |
|
17 |
|
matrix<size, size, T> |
17 |
18 |
|
|
18 |
|
T_IMPL MATRIX4 |
|
19 |
|
look_at(const VECTOR3& pos, const VECTOR3& orient, const VECTOR3& up, |
|
20 |
|
const VECTOR3 &axis_mult) |
|
21 |
|
{ |
|
22 |
|
const VECTOR3 z = orient .normalized() * axis_mult.z; |
|
23 |
|
const VECTOR3 x = cross(up, z).normalized() * axis_mult.x; |
|
24 |
|
const VECTOR3 y = cross(z, x) * axis_mult.y; |
|
25 |
|
const VECTOR3 w = { dot(x, -pos), dot(y, pos), dot(z, pos) }; |
|
26 |
|
return {{{ x.x, y.x, z.x, 0 }, |
|
27 |
|
{ x.y, y.y, z.y, 0 }, |
|
28 |
|
{ x.z, y.z, z.z, 0 }, |
|
29 |
|
{ w.x, w.y, w.z, 1 }}}; |
|
30 |
|
} |
|
|
19 |
|
MATRIXN_IMP scale(T scale) |
|
20 |
|
{ |
|
21 |
|
matrix<size, size, T> m{}; |
|
22 |
|
for (unsigned int i = 0; i < size; ++i) |
|
23 |
|
m._[i][i] = scale; |
|
24 |
|
return m; |
|
25 |
|
} |
|
26 |
|
MATRIXN_IMP scale(T n_scale[size]) |
|
27 |
|
{ |
|
28 |
|
matrix<size, size, T> m{}; |
|
29 |
|
for (unsigned int i = 0; i < size; ++i) |
|
30 |
|
m._[i][i] = n_scale[i]; |
|
31 |
|
} |
|
32 |
|
T_IMPL MATRIX(4) |
|
33 |
|
matrix_3x4(VEC_ARG(3) x, VEC_ARG(3) y, VEC_ARG(3) z, VEC_ARG(3) w = {}) { |
|
34 |
|
return {{{ x.x, y.x, z.x, 0 }, |
|
35 |
|
{ x.y, y.y, z.y, 0 }, |
|
36 |
|
{ x.z, y.z, z.z, 0 }, |
|
37 |
|
{ w.x, w.y, w.z, 1 }}}; |
|
38 |
|
} |
|
39 |
|
T_IMPL MATRIX(4) // x, y, z are normalized axis-directions |
|
40 |
|
look_at(VEC_ARG(3) x, VEC_ARG(3) y, VEC_ARG(3) z, VEC_ARG(3) pos = {}) { |
|
41 |
|
const VECTOR(3) w = { - dot(x, pos), - dot(y, pos), - dot(z, pos) }; |
|
42 |
|
return matrix_3x4(x, y, z, w); |
|
43 |
|
} |
|
44 |
|
T_IMPL MATRIX(4) |
|
45 |
|
translation(VEC_ARG(3) pos) { |
|
46 |
|
auto mat = scale<4, T>(1); |
|
47 |
|
mat[3].template part<0,3>() = pos; |
|
48 |
|
return mat; |
|
49 |
|
} |
|
50 |
|
T_IMPL MATRIX(3) |
|
51 |
|
rotation(VEC_ARG(3) x, VEC_ARG(3) y, VEC_ARG(3) z) { |
|
52 |
|
return {{{x.x, y.x, z.x}, |
|
53 |
|
{x.y, y.y, z.y}, |
|
54 |
|
{x.z, y.z, z.z}}}; |
|
55 |
|
} |
|
56 |
|
T_IMPL MATRIX(3) |
|
57 |
|
rotation(const vector<3, vector<3, T>> &axis) { |
|
58 |
|
return rotation(axis.x, axis.y, axis.z); |
|
59 |
|
} |
|
60 |
|
T_IMPL MATRIX(4) |
|
61 |
|
projection(T fov_y, T aspect_x_to_y, T z_near, T z_far) |
|
62 |
|
{ |
|
63 |
|
const T y_scale = 1 / std::tan(fov_y / 2); |
|
64 |
|
const T x_scale = y_scale / aspect_x_to_y; |
|
65 |
|
const T z_scale = z_far / (z_far - z_near); |
|
66 |
|
const T z_shift = - z_scale * z_near; |
|
67 |
|
return {{{ x_scale, 0, 0, 0 }, |
|
68 |
|
{ 0, y_scale, 0, 0 }, |
|
69 |
|
{ 0, 0, z_scale, 1 }, |
|
70 |
|
{ 0, 0, z_shift, 0 }}}; |
|
71 |
|
} |
|
72 |
|
T_IMPL MATRIX(3) |
|
73 |
|
rotation(const VECTOR(3)& unit, T radians) |
|
74 |
|
{ |
|
75 |
|
auto &x = unit._[0], &y = unit._[1], &z = unit._[2]; |
|
76 |
|
auto c = gcem::cos(radians), s = gcem::sin(radians), t = math::one<T> - c; |
|
77 |
|
return {{{ t*x*x + c, t*x*y - s*z, t*x*z + s*y }, |
|
78 |
|
{ t*x*y + s*z, t*y*y + c, t*y*z - s*x }, |
|
79 |
|
{ t*x*z - s*y, t*y*z + s*x, t*z*z + c }}}; |
|
80 |
|
} |
|
81 |
|
T_IMPL MATRIX(3) |
|
82 |
|
rotation(T x_angle, T y_angle, T z_angle) |
|
83 |
|
{ |
|
84 |
|
T cosX = gcem::cos<T>(x_angle), sinX = gcem::sin<T>(x_angle); |
|
85 |
|
T cosY = gcem::cos<T>(y_angle), sinY = gcem::sin<T>(y_angle); |
|
86 |
|
T cosZ = gcem::cos<T>(z_angle), sinZ = gcem::sin<T>(z_angle); |
31 |
87 |
|
|
32 |
|
T_IMPL MATRIX4 |
|
33 |
|
projection(T fov_y, T aspect_x_to_y, T z_near, T z_far) |
|
34 |
|
{ |
|
35 |
|
const T y_scale = 1 / std::tan(fov_y / 2); |
|
36 |
|
const T x_scale = y_scale / aspect_x_to_y; |
|
37 |
|
const T z_scale = z_far / (z_far - z_near); |
|
38 |
|
const T z_shift = - z_scale * z_near; |
|
39 |
|
return {{{ x_scale, 0, 0, 0 }, |
|
40 |
|
{ 0, y_scale, 0, 0 }, |
|
41 |
|
{ 0, 0, z_scale, 1 }, |
|
42 |
|
{ 0, 0, z_shift, 0 }}}; |
|
43 |
|
} |
|
44 |
|
|
|
45 |
|
T_IMPL MATRIX4 lookAtUpLH(const VECTOR3& position, const VECTOR3& up, const VECTOR3& right) |
|
46 |
|
{ |
|
47 |
|
const VECTOR3 point = normalize(up); |
|
48 |
|
const VECTOR3 rightNormalized = normalize(right); |
|
49 |
|
const VECTOR3 bottom = cross(point, right); |
|
50 |
|
|
|
51 |
|
return {{{ rightNormalized.x, bottom.x, point.x, 0 }, |
|
52 |
|
{ rightNormalized.y, bottom.y, point.y, 0 }, |
|
53 |
|
{ rightNormalized.z, bottom.z, point.z, 0 }, |
|
54 |
|
{ - dot(rightNormalized, position), - dot(bottom, position), - dot(point, position), one<T> }}}; |
|
55 |
|
} |
|
56 |
|
T_IMPL MATRIX4 lookAtUpRH(const VECTOR3& position, const VECTOR3& up, const VECTOR3& left) |
|
57 |
|
{ |
|
58 |
|
const VECTOR3 point = normalize(up); |
|
59 |
|
const VECTOR3 leftNormalized = normalize(left); |
|
60 |
|
const VECTOR3 bottom = cross(left, point); |
|
61 |
|
|
|
62 |
|
return {{{ leftNormalized.x, bottom.x, - point.x, 0 }, |
|
63 |
|
{ leftNormalized.y, bottom.y, - point.y, 0 }, |
|
64 |
|
{ leftNormalized.z, bottom.z, - point.z, 0 }, |
|
65 |
|
{ - dot(leftNormalized, position), - dot(bottom, position), dot(point, position), one<T> }}}; |
|
66 |
|
} |
|
67 |
|
|
|
68 |
|
|
|
69 |
|
T_IMPL matrix<3, 3, T> rotation(const VECTOR3& unit, T radians) |
|
70 |
|
{ |
|
71 |
|
auto &x = unit._[0], &y = unit._[1], &z = unit._[2]; |
|
72 |
|
auto c = gcem::cos(radians), s = gcem::sin(radians), t = math::one<T> - c; |
|
73 |
|
return {{{ t*x*x + c, t*x*y - s*z, t*x*z + s*y }, |
|
74 |
|
{ t*x*y + s*z, t*y*y + c, t*y*z - s*x }, |
|
75 |
|
{ t*x*z - s*y, t*y*z + s*x, t*z*z + c }}}; |
|
76 |
|
} |
|
77 |
|
|
|
78 |
|
T_IMPL matrix<3, 3, T> rotation(T x_angle, T y_angle, T z_angle) |
|
79 |
|
{ |
|
80 |
|
T cosX = gcem::cos<T>(x_angle), sinX = gcem::sin<T>(x_angle); |
|
81 |
|
T cosY = gcem::cos<T>(y_angle), sinY = gcem::sin<T>(y_angle); |
|
82 |
|
T cosZ = gcem::cos<T>(z_angle), sinZ = gcem::sin<T>(z_angle); |
|
83 |
|
|
|
84 |
|
return {{{ cosY*cosZ, -cosX*sinZ + sinX*sinY*cosZ, sinX*sinZ + cosX*sinY*cosZ }, |
|
85 |
|
{ cosY*sinZ, cosX*cosZ + sinX*sinY*sinZ, -sinX*cosZ + cosX*sinY*sinZ }, |
|
86 |
|
{ -sinY, sinX*cosY, cosX*cosY }}}; |
|
87 |
|
} |
|
88 |
|
|
|
89 |
|
MATRIXN_IMP scale(T scale) |
|
90 |
|
{ |
|
91 |
|
matrix<size, size, T> m{}; |
|
92 |
|
for (unsigned int i = 0; i < size; ++i) |
|
93 |
|
m._[i][i] = scale; |
|
94 |
|
return m; |
|
95 |
|
} |
|
96 |
|
|
|
97 |
|
MATRIXN_IMP scale(T n_scale[size]) |
|
98 |
|
{ |
|
99 |
|
matrix<size, size, T> m{}; |
|
100 |
|
for (unsigned int i = 0; i < size; ++i) |
|
101 |
|
m._[i][i] = n_scale[i]; |
|
102 |
|
} |
|
|
88 |
|
return {{{ cosY*cosZ, -cosX*sinZ + sinX*sinY*cosZ, sinX*sinZ + cosX*sinY*cosZ }, |
|
89 |
|
{ cosY*sinZ, cosX*cosZ + sinX*sinY*sinZ, -sinX*cosZ + cosX*sinY*sinZ }, |
|
90 |
|
{ -sinY, sinX*cosY, cosX*cosY }}}; |
|
91 |
|
} |
103 |
92 |
|
|
104 |
93 |
#undef MATRIXN_IMP |
#undef MATRIXN_IMP |
105 |
94 |
#undef T_IMPL |
#undef T_IMPL |
106 |
|
#undef MATRIX4 |
|
107 |
|
#undef VECTOR4 |
|
|
95 |
|
#undef VECTOR |
|
96 |
|
#undef MATRIX |
108 |
97 |
} |
} |
File include/math/misc.h changed (mode: 100644) (index 169e41b..4b798a1) |
5 |
5 |
|
|
6 |
6 |
namespace math |
namespace math |
7 |
7 |
{ |
{ |
8 |
|
template<typename T> constexpr inline |
|
9 |
|
T radians(const T& degrees) |
|
10 |
|
{ |
|
11 |
|
return degrees * pi<T> / cast<T>(180); |
|
12 |
|
} |
|
|
8 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
9 |
|
T radians(const T& degrees) { |
|
10 |
|
return degrees * pi<T> / cast<T>(180); |
|
11 |
|
} |
|
12 |
|
template<typename T, typename = typename std::enable_if< |
|
13 |
|
std::is_floating_point<T>::value, int>::type> |
|
14 |
|
[[nodiscard]] constexpr inline |
|
15 |
|
T inversesqrt(const T &v) { |
|
16 |
|
return one<T> / gcem::sqrt(v); |
|
17 |
|
} |
13 |
18 |
|
|
14 |
|
template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, int>::type> constexpr inline |
|
15 |
|
T inversesqrt(const T &v) |
|
16 |
|
{ |
|
17 |
|
return one<T> / gcem::sqrt(v); |
|
|
19 |
|
namespace detail |
|
20 |
|
{ |
|
21 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
22 |
|
T SignAndMagnitudeToBiased(T value) { |
|
23 |
|
if (kSignBitMask<T> & value) // sam represents a negative number. |
|
24 |
|
return ~value + 1; |
|
25 |
|
else // sam represents a positive number. |
|
26 |
|
return kSignBitMask<T> | value; |
18 |
27 |
} |
} |
19 |
|
|
|
20 |
|
namespace __hiden |
|
21 |
|
{ |
|
22 |
|
template<typename T> constexpr inline |
|
23 |
|
T SignAndMagnitudeToBiased(T value) |
|
24 |
|
{ |
|
25 |
|
if (kSignBitMask<T> & value) // sam represents a negative number. |
|
26 |
|
return ~value + 1; |
|
27 |
|
else // sam represents a positive number. |
|
28 |
|
return kSignBitMask<T> | value; |
|
29 |
|
} |
|
30 |
|
|
|
31 |
|
template<typename T> constexpr inline |
|
32 |
|
T DistanceBetweenSignAndMagnitudeNumbers(T value1, T value2) |
|
33 |
|
{ |
|
34 |
|
T biased1 = SignAndMagnitudeToBiased(value1); |
|
35 |
|
T biased2 = SignAndMagnitudeToBiased(value2); |
|
36 |
|
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); |
|
37 |
|
} |
|
|
28 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
29 |
|
T DistanceBetweenSignAndMagnitudeNumbers(T value1, T value2) { |
|
30 |
|
T biased1 = SignAndMagnitudeToBiased(value1); |
|
31 |
|
T biased2 = SignAndMagnitudeToBiased(value2); |
|
32 |
|
return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); |
38 |
33 |
} |
} |
|
34 |
|
} |
39 |
35 |
|
|
40 |
|
template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, int>::type> inline |
|
41 |
|
bool float_almost_equals(T value1, T value2) |
|
42 |
|
{ |
|
43 |
|
using B = typename type_of_size<sizeof(T)>::type; |
|
44 |
|
return __hiden::DistanceBetweenSignAndMagnitudeNumbers(cast_bits<B>(value1), cast_bits<B>(value2)) <= kMaxUlps; |
|
45 |
|
} |
|
|
36 |
|
template<typename T, typename = typename std::enable_if< |
|
37 |
|
std::is_floating_point<T>::value, int>::type> [[nodiscard]] inline |
|
38 |
|
bool float_almost_equals(T value1, T value2) { |
|
39 |
|
using B = typename type_of_size<sizeof(T)>::type; |
|
40 |
|
return detail::DistanceBetweenSignAndMagnitudeNumbers |
|
41 |
|
(cast_bits<B>(value1), cast_bits<B>(value2)) <= kMaxUlps; |
|
42 |
|
} |
46 |
43 |
|
|
47 |
|
template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value, int>::type> constexpr inline |
|
48 |
|
bool float_almost_equals_constexpr(T value1, T value2, T allowed_error = std::numeric_limits<T>::epsilon()) |
|
49 |
|
{ |
|
50 |
|
T diff = value1 - value2; |
|
51 |
|
if (diff < 0) |
|
52 |
|
diff *= -1; |
|
53 |
|
return diff <= allowed_error; |
|
54 |
|
} |
|
|
44 |
|
template<typename T, typename = typename std::enable_if< |
|
45 |
|
std::is_floating_point<T>::value, int>::type> |
|
46 |
|
[[nodiscard]] constexpr inline |
|
47 |
|
bool float_almost_equals_constexpr(T value1, T value2, |
|
48 |
|
T allowed_error = epsilon<T>) { |
|
49 |
|
T diff = value1 - value2; |
|
50 |
|
if (diff < 0) |
|
51 |
|
diff *= -1; |
|
52 |
|
return diff <= allowed_error; |
|
53 |
|
} |
55 |
54 |
|
|
56 |
|
template<typename T> constexpr inline |
|
57 |
|
typename std::enable_if<std::is_unsigned<T>::value, T>:: |
|
58 |
|
type round_up(T number, T alignment) { |
|
59 |
|
T mod = number % alignment; |
|
60 |
|
if (mod == 0) |
|
61 |
|
return number; |
|
62 |
|
return number - mod + alignment; |
|
63 |
|
} |
|
64 |
|
template<typename T> constexpr inline |
|
65 |
|
typename std::enable_if<std::is_unsigned<T>::value, T>:: |
|
66 |
|
type round_down(T number, T alignment) { |
|
67 |
|
return number - number % alignment; |
|
68 |
|
} |
|
|
55 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
56 |
|
typename std::enable_if<std::is_unsigned<T>::value, T>:: |
|
57 |
|
type round_up(T number, T alignment) { |
|
58 |
|
T mod = number % alignment; |
|
59 |
|
if (mod == 0) |
|
60 |
|
return number; |
|
61 |
|
return number - mod + alignment; |
|
62 |
|
} |
|
63 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
64 |
|
typename std::enable_if<std::is_unsigned<T>::value, T>:: |
|
65 |
|
type round_down(T number, T alignment) { |
|
66 |
|
return number - number % alignment; |
|
67 |
|
} |
69 |
68 |
|
|
70 |
|
template<typename T> |
|
71 |
|
[[nodiscard]] constexpr inline bool is_power_of_2(T v) |
|
72 |
|
{ |
|
73 |
|
static_assert (std::is_integral<T>::value); |
|
74 |
|
return (v != 0) && ((v & (v - 1)) == 0); |
|
75 |
|
} |
|
|
69 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
70 |
|
bool is_power_of_2(T v) { |
|
71 |
|
static_assert (std::is_integral<T>::value); |
|
72 |
|
return (v != 0) && ((v & (v - 1)) == 0); |
|
73 |
|
} |
|
74 |
|
|
|
75 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
76 |
|
T medium(const T &v1, const T &v2) { |
|
77 |
|
return (v1 + v2) / 2; |
|
78 |
|
} |
76 |
79 |
} |
} |
File include/math/vector/base.h changed (mode: 100644) (index 227bde2..8b31734) |
12 |
12 |
|
|
13 |
13 |
namespace math::detail |
namespace math::detail |
14 |
14 |
{ |
{ |
15 |
|
template<int SIZE, typename T> |
|
16 |
|
struct vector_base { T _[SIZE]; }; |
|
17 |
|
|
|
18 |
|
template<typename T> |
|
19 |
|
struct vector_base<1, T> |
|
20 |
|
{ union { T _[1]; T x; };}; |
|
21 |
|
|
|
22 |
|
template<typename T> |
|
23 |
|
struct vector_base<2, T> |
|
24 |
|
{ union { T _[2]; struct { T x, y; }; struct { T u, v; }; };}; |
|
25 |
|
|
|
26 |
|
template<typename T> |
|
27 |
|
struct vector_base<3, T> |
|
28 |
|
{ union { T _[3]; struct { T x, y, z; }; }; }; |
|
29 |
|
|
|
30 |
|
template<typename T> |
|
31 |
|
struct vector_base<4, T> |
|
32 |
|
{ union { T _[4]; struct { T x, y, z, w; }; }; }; |
|
|
15 |
|
template<int SIZE, typename T> |
|
16 |
|
struct vector_base { |
|
17 |
|
T _[SIZE]; |
|
18 |
|
}; |
|
19 |
|
template<typename T> |
|
20 |
|
struct vector_base<1, T> { |
|
21 |
|
union { T _[1]; T x; }; |
|
22 |
|
}; |
|
23 |
|
template<typename T> |
|
24 |
|
struct vector_base<2, T> { |
|
25 |
|
union { T _[2]; struct { T x, y; }; struct { T u, v; }; }; |
|
26 |
|
}; |
|
27 |
|
template<typename T> |
|
28 |
|
struct vector_base<3, T> { |
|
29 |
|
union { T _[3]; struct { T x, y, z; }; }; |
|
30 |
|
}; |
|
31 |
|
template<typename T> |
|
32 |
|
struct vector_base<4, T> { |
|
33 |
|
union { T _[4]; struct { T x, y, z, w; }; }; |
|
34 |
|
}; |
33 |
35 |
} |
} |
|
36 |
|
|
34 |
37 |
namespace math |
namespace math |
35 |
38 |
{ |
{ |
36 |
|
enum VecI { X, Y, Z, W, U = X, V = Y }; |
|
37 |
|
|
|
38 |
|
template<int SIZE, typename T> |
|
39 |
|
struct vector : public detail::vector_base<SIZE, T> |
|
40 |
|
{ |
|
41 |
|
static_assert(sizeof(detail::vector_base<SIZE, T>) == sizeof(T) * SIZE); |
|
42 |
|
constexpr static const unsigned int COUNT = SIZE; |
|
43 |
|
template<typename T2> |
|
44 |
|
using vec_other = vector<SIZE, T2>; |
|
45 |
|
using detail::vector_base<SIZE, T>::_; |
|
46 |
|
|
|
47 |
|
T2_TEM NDIS CT static vector from(const vec_other<T2> &other); |
|
48 |
|
|
|
49 |
|
T2_TEM NDIS CT operator vec_other<T2>() |
|
50 |
|
{ return vector<SIZE, T2>::from(*this); } |
|
51 |
|
|
|
52 |
|
U_TEM CT IF_FLOAT(true, U, bool) operator == (const vector&) const; |
|
53 |
|
U_TEM CT IF_FLOAT(false, U, bool) operator == (const vector&) const; |
|
54 |
|
NDIS CT bool operator < (const vector&) const; |
|
55 |
|
NDIS CT bool operator > (const vector&) const; |
|
56 |
|
NDIS CT bool operator != (const vector&vc)const {return not(*this == vc);} |
|
57 |
|
|
|
58 |
|
T_NUM NDIS CT T& operator[](N i) {return _[i];} |
|
59 |
|
T_NUM NDIS CT const T& operator[](N i) const {return _[i];} |
|
60 |
|
|
|
61 |
|
T2_TEM NDIS CT vector operator + (const vec_other<T2>&) const; |
|
62 |
|
T2_TEM NDIS CT vector operator - (const vec_other<T2>&) const; |
|
63 |
|
T2_TEM NDIS CT vector operator * (const vec_other<T2>&) const; |
|
64 |
|
T2_TEM NDIS CT vector operator / (const vec_other<T2>&) const; |
|
65 |
|
T2_TEM CT vector& operator += (const vec_other<T2>&); |
|
66 |
|
T2_TEM CT vector& operator -= (const vec_other<T2>&); |
|
67 |
|
T2_TEM CT vector& operator *= (const vec_other<T2>&); |
|
68 |
|
T2_TEM CT vector& operator /= (const vec_other<T2>&); |
|
69 |
|
|
|
70 |
|
NDIS CT vector operator - () const; |
|
71 |
|
NDIS CT vector operator + (const T&) const; |
|
72 |
|
NDIS CT vector operator - (const T&) const; |
|
73 |
|
NDIS CT vector operator * (const T&) const; |
|
74 |
|
NDIS CT vector operator / (const T&) const; |
|
75 |
|
CT vector& operator += (const T&); |
|
76 |
|
CT vector& operator -= (const T&); |
|
77 |
|
CT vector& operator *= (const T&); |
|
78 |
|
CT vector& operator /= (const T&); |
|
79 |
|
|
|
80 |
|
NDIS CT T* begin() {return _; } |
|
81 |
|
NDIS CT T* end () {return _ + SIZE;} |
|
82 |
|
NDIS CT const T* begin() const {return _; } |
|
83 |
|
NDIS CT const T* end () const {return _ + SIZE;} |
|
84 |
|
|
|
85 |
|
|
|
86 |
|
NDIS CT bool all_less_equal (const vector&) const; |
|
87 |
|
NDIS CT bool all_greater_equal(const vector&) const; |
|
88 |
|
NDIS CT bool all_equal (const vector&) const; |
|
89 |
|
NDIS CT bool all_greater (const vector&) const; |
|
90 |
|
NDIS CT bool all_less (const vector&) const; |
|
91 |
|
|
|
92 |
|
NDIS CT bool all_less_equal (const T&) const; |
|
93 |
|
NDIS CT bool all_greater_equal(const T&) const; |
|
94 |
|
NDIS CT bool all_equal (const T&) const; |
|
95 |
|
NDIS CT bool all_greater (const T&) const; |
|
96 |
|
NDIS CT bool all_less (const T&) const; |
|
97 |
|
|
|
98 |
|
NDIS CT T all_scale() const; |
|
99 |
|
NDIS CT T all_summ() const; |
|
100 |
|
NDIS CT T area() const {return all_scale();} |
|
101 |
|
NDIS CT T length() const; |
|
102 |
|
|
|
103 |
|
NDIS CT vector normalized() const; |
|
104 |
|
CT vector& normalize() { return *this = normalized(); } |
|
105 |
|
NDIS CT vector abs() const; |
|
106 |
|
|
|
107 |
|
U_TEM NDIS CT typename std::enable_if<std::is_same<float, U>::value |
|
108 |
|
and std::is_floating_point<U>::value, |
|
109 |
|
vector>::type inversesqrt() const; |
|
110 |
|
U_TEM NDIS CT typename std::enable_if<not std::is_same<float, U>::value |
|
111 |
|
and std::is_floating_point<U>::value, |
|
112 |
|
vector>::type inversesqrt() const; |
|
113 |
|
|
|
114 |
|
NDIS CT vector rotated(const T& angle) const; |
|
115 |
|
NDIS CT vector rotated(const T& angle, const vector& unit) const; |
|
116 |
|
|
|
117 |
|
template<int PART_OFFSET, int PART_SIZE> |
|
118 |
|
NDIS CT vector<PART_SIZE, T>& part(); |
|
119 |
|
template<int PART_OFFSET, int PART_SIZE> |
|
120 |
|
NDIS CT const vector<PART_SIZE, T>& part() const; |
|
121 |
|
}; |
|
|
39 |
|
enum VecI { X, Y, Z, W, U = X, V = Y }; |
|
40 |
|
|
|
41 |
|
template<int SIZE, typename T> |
|
42 |
|
struct vector : detail::vector_base<SIZE, T> |
|
43 |
|
{ |
|
44 |
|
void __test_function() {} |
|
45 |
|
|
|
46 |
|
static_assert(sizeof(detail::vector_base<SIZE, T>) == sizeof(T) * SIZE); |
|
47 |
|
using value_t = T; |
|
48 |
|
constexpr static const unsigned int COUNT = SIZE; |
|
49 |
|
template<typename T2> |
|
50 |
|
using vec_other = vector<SIZE, T2>; |
|
51 |
|
using base = detail::vector_base<SIZE, T>; |
|
52 |
|
using base::_; |
|
53 |
|
|
|
54 |
|
vector() = default; |
|
55 |
|
template<typename ... Types, |
|
56 |
|
typename std::enable_if<sizeof...(Types) == SIZE, int>::type = 0> |
|
57 |
|
constexpr vector(Types ... s) : base{static_cast<T>(s)... } {} |
|
58 |
|
|
|
59 |
|
T2_TEM NDIS CT static vector from(const vec_other<T2> &other); |
|
60 |
|
|
|
61 |
|
T2_TEM NDIS CT operator vec_other<T2>() |
|
62 |
|
{ return vector<SIZE, T2>::from(*this); } |
|
63 |
|
|
|
64 |
|
U_TEM CT IF_FLOAT(true, U, bool) operator == (const vector&) const; |
|
65 |
|
U_TEM CT IF_FLOAT(false, U, bool) operator == (const vector&) const; |
|
66 |
|
NDIS CT bool operator < (const vector&) const; |
|
67 |
|
NDIS CT bool operator > (const vector&) const; |
|
68 |
|
NDIS CT bool operator != (const vector&vc)const {return not(*this == vc);} |
|
69 |
|
|
|
70 |
|
T_NUM NDIS CT T& operator[](N i) {return _[i];} |
|
71 |
|
T_NUM NDIS CT const T& operator[](N i) const {return _[i];} |
|
72 |
|
|
|
73 |
|
T2_TEM NDIS CT vector operator + (const vec_other<T2>&) const; |
|
74 |
|
T2_TEM NDIS CT vector operator - (const vec_other<T2>&) const; |
|
75 |
|
T2_TEM NDIS CT vector operator * (const vec_other<T2>&) const; |
|
76 |
|
T2_TEM NDIS CT vector operator / (const vec_other<T2>&) const; |
|
77 |
|
T2_TEM CT vector& operator += (const vec_other<T2>&); |
|
78 |
|
T2_TEM CT vector& operator -= (const vec_other<T2>&); |
|
79 |
|
T2_TEM CT vector& operator *= (const vec_other<T2>&); |
|
80 |
|
T2_TEM CT vector& operator /= (const vec_other<T2>&); |
|
81 |
|
|
|
82 |
|
NDIS CT vector operator - () const; |
|
83 |
|
NDIS CT vector operator + (const T&) const; |
|
84 |
|
NDIS CT vector operator - (const T&) const; |
|
85 |
|
NDIS CT vector operator * (const T&) const; |
|
86 |
|
NDIS CT vector operator / (const T&) const; |
|
87 |
|
CT vector& operator += (const T&); |
|
88 |
|
CT vector& operator -= (const T&); |
|
89 |
|
CT vector& operator *= (const T&); |
|
90 |
|
CT vector& operator /= (const T&); |
|
91 |
|
|
|
92 |
|
NDIS CT T* begin() {return _; } |
|
93 |
|
NDIS CT T* end () {return _ + SIZE;} |
|
94 |
|
NDIS CT const T* begin() const {return _; } |
|
95 |
|
NDIS CT const T* end () const {return _ + SIZE;} |
|
96 |
|
|
|
97 |
|
|
|
98 |
|
NDIS CT bool all_less_equal (const vector&) const; |
|
99 |
|
NDIS CT bool all_greater_equal(const vector&) const; |
|
100 |
|
NDIS CT bool all_equal (const vector&) const; |
|
101 |
|
NDIS CT bool all_greater (const vector&) const; |
|
102 |
|
NDIS CT bool all_less (const vector&) const; |
|
103 |
|
|
|
104 |
|
NDIS CT bool all_less_equal (const T&) const; |
|
105 |
|
NDIS CT bool all_greater_equal(const T&) const; |
|
106 |
|
NDIS CT bool all_equal (const T&) const; |
|
107 |
|
NDIS CT bool all_greater (const T&) const; |
|
108 |
|
NDIS CT bool all_less (const T&) const; |
|
109 |
|
|
|
110 |
|
NDIS CT T all_scale() const; |
|
111 |
|
NDIS CT T all_summ() const; |
|
112 |
|
NDIS CT T area() const {return all_scale();} |
|
113 |
|
NDIS CT T volume() const {return all_scale();} |
|
114 |
|
NDIS CT T length() const; |
|
115 |
|
|
|
116 |
|
NDIS CT vector normalized() const; |
|
117 |
|
CT vector& normalize() { return *this = normalized(); } |
|
118 |
|
NDIS CT vector abs() const; |
|
119 |
|
|
|
120 |
|
U_TEM NDIS CT typename std::enable_if<std::is_same<float, U>::value |
|
121 |
|
and std::is_floating_point<U>::value, vector>:: |
|
122 |
|
type inversesqrt() const; |
|
123 |
|
U_TEM NDIS CT typename std::enable_if<not std::is_same<float, U>::value |
|
124 |
|
and std::is_floating_point<U>::value, vector>:: |
|
125 |
|
type inversesqrt() const; |
|
126 |
|
|
|
127 |
|
NDIS CT vector rotated(const T& angle) const; |
|
128 |
|
NDIS CT vector rotated(const T& angle, const vector& unit) const; |
|
129 |
|
CT void rotate(const T&angle, const vector &unit) |
|
130 |
|
{ *this = rotated(angle, unit); } |
|
131 |
|
|
|
132 |
|
template<int PART_OFFSET, int PART_SIZE> |
|
133 |
|
NDIS CT vector<PART_SIZE, T>& part(); |
|
134 |
|
template<int PART_OFFSET, int PART_SIZE> |
|
135 |
|
NDIS CT const vector<PART_SIZE, T>& part() const; |
|
136 |
|
}; |
122 |
137 |
} |
} |
123 |
138 |
|
|
124 |
139 |
#undef T_NUM |
#undef T_NUM |
File include/math/vector/vector_functions.h changed (mode: 100644) (index 1df8ffc..6379980) |
4 |
4 |
|
|
5 |
5 |
namespace math |
namespace math |
6 |
6 |
{ |
{ |
7 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
8 |
|
vector<3,T> cross(const vector<3,T>&l, const vector<3,T>&r) { |
|
9 |
|
return { l._[1]*r._[2] - l._[2]*r._[1], |
|
10 |
|
l._[2]*r._[0] - l._[0]*r._[2], |
|
11 |
|
l._[0]*r._[1] - l._[1]*r._[0] }; |
|
12 |
|
} |
|
13 |
|
|
|
14 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
15 |
|
T angle_if_both_normalized(const vector<3,T>&l, const vector<3,T>&r) |
|
16 |
|
{ return gcem::acos(dot(l, r)); } |
|
17 |
|
|
|
18 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
19 |
|
T angle(const vector<3,T>&l, const vector<3,T>&r) { |
|
20 |
|
return angle_if_both_normalized(l.normalized(), r.normalized()); |
|
21 |
|
} |
|
22 |
|
|
|
23 |
|
template<int SIZE, typename T> [[nodiscard]] constexpr inline |
|
24 |
|
T dot(const vector<SIZE, T>&l, const vector<SIZE, T>&r) { |
|
25 |
|
T t = l._[0] * r._[0]; |
|
26 |
|
for (unsigned int i = 1; i < SIZE; ++i) |
|
27 |
|
t += l._[i] * r._[i]; |
|
28 |
|
return t; |
|
29 |
|
} |
|
30 |
|
|
|
31 |
|
template<int S, typename T> [[nodiscard]] constexpr inline |
|
32 |
|
vector<S, T> medium(const vector<S,T>&l, const vector<S,T>&r) |
|
33 |
|
{ return (l + r) / two<T>; } |
|
|
7 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
8 |
|
vector<3,T> cross(const vector<3,T>&l, const vector<3,T>&r) { |
|
9 |
|
return { l._[1]*r._[2] - l._[2]*r._[1], |
|
10 |
|
l._[2]*r._[0] - l._[0]*r._[2], |
|
11 |
|
l._[0]*r._[1] - l._[1]*r._[0] }; |
|
12 |
|
} |
|
13 |
|
|
|
14 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
15 |
|
T angle_if_both_normalized(const vector<3,T>&l, const vector<3,T>&r) { |
|
16 |
|
return gcem::acos(dot(l, r)); |
|
17 |
|
} |
|
18 |
|
|
|
19 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
20 |
|
T angle(const vector<3,T>&l, const vector<3,T>&r) { |
|
21 |
|
return angle_if_both_normalized(l.normalized(), r.normalized()); |
|
22 |
|
} |
|
23 |
|
|
|
24 |
|
template<int SIZE, typename T> [[nodiscard]] constexpr inline |
|
25 |
|
T dot(const vector<SIZE, T>&l, const vector<SIZE, T>&r) { |
|
26 |
|
T t = l._[0] * r._[0]; |
|
27 |
|
for (unsigned int i = 1; i < SIZE; ++i) |
|
28 |
|
t += l._[i] * r._[i]; |
|
29 |
|
return t; |
|
30 |
|
} |
|
31 |
|
|
|
32 |
|
template<int S, typename T> [[nodiscard]] constexpr inline |
|
33 |
|
vector<S, T> medium(const vector<S,T>&l, const vector<S,T>&r) { |
|
34 |
|
return (l + r) / two<T>; |
|
35 |
|
} |
|
36 |
|
|
|
37 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
38 |
|
T distance(const vector<4,T> &plane, const vector<3,T> &point) { |
|
39 |
|
auto normal = plane.template part<0,3>(); |
|
40 |
|
return dot(normal, point) + plane.w; |
|
41 |
|
} |
|
42 |
|
|
|
43 |
|
template<typename T> [[nodiscard]] constexpr inline |
|
44 |
|
vector<3,T> projection(const vector<4,T> &plane, const vector<3,T> &point) { |
|
45 |
|
return point - plane.template part<0,3>() * distance(plane, point); |
|
46 |
|
} |
|
47 |
|
|
|
48 |
|
template<int SIZE, typename T> [[nodiscard]] constexpr inline |
|
49 |
|
vector<SIZE,T> normalize(const vector<SIZE, T> &v) { |
|
50 |
|
return v.normalized(); |
|
51 |
|
} |
34 |
52 |
} |
} |