-
Notifications
You must be signed in to change notification settings - Fork 0
/
math.hxx
128 lines (101 loc) · 2.38 KB
/
math.hxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#pragma once
#include <glm/glm.hpp>
using namespace glm;
template <int N>
using vecn = glm::vec<N, float>;
template <int N>
using matn = glm::mat<N, N, float>;
template <int N>
matn<N> diagonal(vecn<N> v) {
matn<N> ret{0.0f};
for (int k = 0; k < N; k++)
ret[k][k] = v[k];
return ret;
}
auto diagonal(float x, float y) {
return diagonal(vecn<2> {x, y});
}
auto diagonal(float x, float y, float z) {
return diagonal(vecn<3>{x, y, z});
}
auto diagonal(float x, float y, float z, float w) {
return diagonal(vecn<4>{x, y, z, w});
}
template <typename T>
inline static T sqr(T x) {
return x * x;
}
inline static float smoothstep(float x) {
return 3 * x * x - 2 * x * x * x;
}
inline static float box(float val, vec2 range, float pad) {
float slope1 = 1.0f + (val - range.x) / pad;
float slope2 = 1.0f - (val - range.y) / pad;
float lin = std::min(slope1, slope2);
return smoothstep(glm::clamp(lin, 0.0f, 1.0f));
}
template <int N>
struct tensn {
using mat = matn<N>;
mat data[N];
mat &operator[] (int index) {
return data[index];
}
};
using tens2 = tensn<2>;
using tens3 = tensn<3>;
template <int N>
vecn<N> covar(tensn<N> G, vecn<N> v) {
vecn<N> ret;
for (int k = 0; k < N; k++)
ret[k] = -dot(v, G[k] * v);
return ret;
}
// Decomposed (O^−1 D O) symmetrical matrix
template <int N>
struct decompn {
matn<N> ortho; // must be orthogonal
vecn<N> diag; // eigenvalues
operator matn<N> () const {
return transpose(ortho) * diagonal(diag) * ortho;
}
};
using decomp2 = decompn<2>;
using decomp3 = decompn<3>;
inline static uint32_t next_pow2(uint32_t v) {
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
inline static vec2 cross(vec2 v) {
return {-v.y, v.x};
}
using glm::min, glm::max; // bring in scope
inline static float min(vec2 v) {
return min(v.x, v.y);
}
inline static float min(vec3 v) {
return min(min(v.x, v.y), v.z);
}
inline static float min(vec4 v) {
return min(min(v.x, v.y), min(v.z, v.w));
}
inline static float max(vec2 v) {
return max(v.x, v.y);
}
inline static float max(vec3 v) {
return max(max(v.x, v.y), v.z);
}
inline static float max(vec4 v) {
return max(max(v.x, v.y), max(v.z, v.w));
}
#ifndef DIM
#define DIM 3
#endif
using vecd = vecn<DIM>; ///< Вектор размерности по умолчанию
using matd = matn<DIM>; ///< Матрица размерности по умолчанию