Distance3f distance_line3(const float3 p, const float3 a, const float3 b) { const float3 bma = b-a; const float3 bma_u = fast_normalize(bma); const float ab = fast_length(bma); const float3 pma = p - a; const float dotf = dot(pma, bma_u); if (dotf < 0) { Distance3f d = { fast_length(pma), a }; return d; } else if (dotf > ab) { Distance3f d = { fast_length(pma), b }; return d; } else { const float dist = fast_length(cross(pma, bma_u)); const float3 pi = a + (bma_u * dotf); Distance3f d = { dist, pi }; return d; } }
Distance3i distance_geom3( const int3 p, global const int* geometry, global const int3* verts) { // Distance3i best = { INT_MAX, (int3)(0, 0, 0) }; Distance3i best = { INT_MAX, make_int3(0, 0, 0) }; const int num_tris = geometry[1]; const Triangle* tris = (Triangle*)(geometry+2); for (int j = 0; j < num_tris; ++j) { Triangle t = tris[j]; const int3 tri_verts[3] = { (verts[t.s[0]]), (verts[t.s[1]]), (verts[t.s[2]]) }; int3 set_verts[3]; const int num_unique = find_unique(tri_verts, set_verts); if (num_unique == 3) { best = min_pair3i(best, distance_trianglei(p, tri_verts)); } else { // Degenerate triangle if (num_unique == 1) { // Degenerate to a point int3 closest = tri_verts[0]; float3 closest_d = convert_float3(closest); float3 p_d = convert_float3(p); int dist = (int)(fast_length(p_d-closest_d)+0.5f); best = min_pair3i(best, make_dist3(dist, closest)); } else { // Degenerate to a line int3 a = set_verts[0]; int3 b = set_verts[1]; Distance3f dist = distance_line3(convert_float3(p), convert_float3(a), convert_float3(b)); Distance3i disti = make_dist3( // convert_int_rte(dist.d), // convert_int3_rte(dist.p)); convert_int(dist.d), convert_int3(dist.p)); best = min_pair3i(best, disti); } } } return best; }
cuda_device friend T fast_distance(const vector4& v1, const vector4& v2) { return fast_length(v1 - v2); }