-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathendpoints_principal_components.h
105 lines (82 loc) · 2.98 KB
/
endpoints_principal_components.h
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
#ifndef ASTC_ENDPOINTS_PRINCIPAL_COMPONENTS_H_
#define ASTC_ENDPOINTS_PRINCIPAL_COMPONENTS_H_
#ifdef RTTC_USE_ASTCRT
#include <cstddef>
#include "colors.h"
#include "constants.h"
#include "dcheck.h"
#include "matrix.h"
#include "vector.h"
inline vec3f_t mean(const unorm8_t texels[BLOCK_TEXEL_COUNT]) {
vec3i_t sum(0, 0, 0);
for (size_t i = 0; i < BLOCK_TEXEL_COUNT; ++i) {
sum = sum + to_vec3i(texels[i]);
}
return to_vec3f(sum) / static_cast<float>(BLOCK_TEXEL_COUNT);
}
inline void subtract(const unorm8_t texels[BLOCK_TEXEL_COUNT], const vec3f_t& v, vec3f_t output[BLOCK_TEXEL_COUNT]) {
for (size_t i = 0; i < BLOCK_TEXEL_COUNT; ++i) {
output[i] = to_vec3f(texels[i]) - v;
}
}
inline mat3x3f_t covariance(const vec3f_t m[BLOCK_TEXEL_COUNT]) {
mat3x3f_t cov;
for (size_t i = 0; i < 3; ++i) {
for (size_t j = 0; j < 3; ++j) {
float s = 0;
for (size_t k = 0; k < BLOCK_TEXEL_COUNT; ++k) {
s += m[k].components[i] * m[k].components[j];
}
cov.at(i, j) = s / static_cast<float>(BLOCK_TEXEL_COUNT - 1);
}
}
return cov;
}
inline void principal_component_analysis(const unorm8_t texels[BLOCK_TEXEL_COUNT], vec3f_t& line_k, vec3f_t& line_m) {
// Since we are working with fixed sized blocks count we can cap count. This
// avoids dynamic allocation.
//DCHECK(count <= BLOCK_TEXEL_COUNT);
line_m = mean(texels);
vec3f_t n[BLOCK_TEXEL_COUNT];
subtract(texels, line_m, n);
mat3x3f_t w = covariance(n);
eigen_vector(w, line_k);
}
//suppost alpha
inline vec4f_t mean_alpha(const unorm8_t texels[BLOCK_TEXEL_COUNT]) {
vec4i_t sum(0, 0, 0, 0);
for (size_t i = 0; i < BLOCK_TEXEL_COUNT; ++i) {
sum = sum + to_vec4i(texels[i]);
}
return to_vec4f(sum) / static_cast<float>(BLOCK_TEXEL_COUNT);
}
inline mat4x4f_t covariance(const vec4f_t m[BLOCK_TEXEL_COUNT]) {
mat4x4f_t cov;
for (size_t i = 0; i < 4; ++i) {
for (size_t j = 0; j < 4; ++j) {
float s = 0;
for (size_t k = 0; k < BLOCK_TEXEL_COUNT; ++k) {
s += m[k].components[i] * m[k].components[j];
}
cov.at(i, j) = s / static_cast<float>(BLOCK_TEXEL_COUNT - 1);
}
}
return cov;
}
inline void subtract(const unorm8_t texels[BLOCK_TEXEL_COUNT], const vec4f_t& v, vec4f_t output[BLOCK_TEXEL_COUNT]) {
for (size_t i = 0; i < BLOCK_TEXEL_COUNT; ++i) {
output[i] = to_vec4f(texels[i]) - v;
}
}
inline void principal_component_analysis(const unorm8_t texels[BLOCK_TEXEL_COUNT], vec4f_t& line_k, vec4f_t& line_m) {
// Since we are working with fixed sized blocks count we can cap count. This
// avoids dynamic allocation.
//DCHECK(count <= BLOCK_TEXEL_COUNT);
line_m = mean_alpha(texels);
vec4f_t n[BLOCK_TEXEL_COUNT];
subtract(texels, line_m, n);
mat4x4f_t w = covariance(n);
eigen_vector(w, line_k);
}
#endif
#endif // ASTC_ENDPOINTS_PRINCIPAL_COMPONENTS_H_