14 return int2{uv * resolution};
18 : uv_map_(uv_map), looptris_(looptris)
20 resolution_ = std::max<int>(3,
std::sqrt(looptris.
size()) * 2);
22 for (
const int looptri_index : looptris.
index_range()) {
23 const MLoopTri &looptri = looptris[looptri_index];
24 const float2 &uv_0 = uv_map_[looptri.
tri[0]];
25 const float2 &uv_1 = uv_map_[looptri.
tri[1]];
26 const float2 &uv_2 = uv_map_[looptri.
tri[2]];
35 for (
int key_x = min_key.x; key_x <= max_key.x; key_x++) {
36 for (
int key_y = min_key.y; key_y <= max_key.y; key_y++) {
37 const int2 key{key_x, key_y};
38 looptris_by_cell_.add(key, looptri_index);
47 const Span<int> looptri_indices = looptris_by_cell_.lookup(cell_key);
49 float best_dist = FLT_MAX;
56 const float edge_epsilon = 0.00001f;
58 for (
const int looptri_index : looptri_indices) {
59 const MLoopTri &looptri = looptris_[looptri_index];
60 const float2 &uv_0 = uv_map_[looptri.
tri[0]];
61 const float2 &uv_1 = uv_map_[looptri.
tri[1]];
62 const float2 &uv_2 = uv_map_[looptri.
tri[2]];
70 const float x_dist =
std::max(-bary_weights.x, bary_weights.x - 1.0f);
71 const float y_dist =
std::max(-bary_weights.y, bary_weights.y - 1.0f);
72 const float z_dist =
std::max(-bary_weights.z, bary_weights.z - 1.0f);
73 const float dist =
MAX3(x_dist, y_dist, z_dist);
75 if (dist <= 0.0f && best_dist <= 0.0f) {
76 const float worse_dist =
std::max(dist, best_dist);
78 if (worse_dist < -edge_epsilon) {
84 if (dist < best_dist) {
86 best_bary_weights = bary_weights;
87 best_looptri = &looptri;
93 if (best_dist < edge_epsilon) {
105 for (const int i : range) {
106 r_results[i] = this->sample(query_uvs[i]);
bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
constexpr int64_t size() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
ReverseUVSampler(const Span< float2 > uv_map, const Span< MLoopTri > looptris)
Result sample(const float2 &query_uv) const
void sample_many(Span< float2 > query_uvs, MutableSpan< Result > r_results) const
static int2 uv_to_cell_key(const float2 &uv, const int resolution)
T clamp(const T &a, const T &min, const T &max)
T min(const T &a, const T &b)
T max(const T &a, const T &b)
void parallel_for(IndexRange range, int64_t grain_size, const Function &function)