static void bmbvh_find_face_segment_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { struct SegmentUserData *bmcb_data = userdata; const BMLoop **ltri = bmcb_data->looptris[index]; float dist, uv[2]; const float *tri_cos[3]; bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage); if (equals_v3v3(bmcb_data->co_a, tri_cos[0]) || equals_v3v3(bmcb_data->co_a, tri_cos[1]) || equals_v3v3(bmcb_data->co_a, tri_cos[2]) || equals_v3v3(bmcb_data->co_b, tri_cos[0]) || equals_v3v3(bmcb_data->co_b, tri_cos[1]) || equals_v3v3(bmcb_data->co_b, tri_cos[2])) { return; } if (isect_ray_tri_v3(ray->origin, ray->direction, tri_cos[0], tri_cos[1], tri_cos[2], &dist, uv) && (dist < hit->dist)) { hit->dist = dist; hit->index = index; copy_v3_v3(hit->no, ltri[0]->f->no); madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist); copy_v2_v2(bmcb_data->uv, uv); } }
static void bmbvh_ray_cast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { struct RayCastUserData *bmcb_data = userdata; const BMLoop **ltri = bmcb_data->looptris[index]; float dist, uv[2]; const float *tri_cos[3]; bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage); if (isect_ray_tri_v3(ray->origin, ray->direction, tri_cos[0], tri_cos[1], tri_cos[2], &dist, uv) && (dist < hit->dist)) { hit->dist = dist; hit->index = index; copy_v3_v3(hit->no, ltri[0]->f->no); copy_v3_v3(hit->co, ray->direction); normalize_v3(hit->co); mul_v3_fl(hit->co, dist); add_v3_v3(hit->co, ray->origin); copy_v2_v2(bmcb_data->uv, uv); } }
static void bmbvh_ray_cast_cb(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) { struct RayCastUserData *bmcb_data = userdata; const BMLoop **ltri = bmcb_data->looptris[index]; float dist, uv[2]; const float *tri_cos[3]; bool isect; bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage); isect = (ray->radius > 0.0f ? isect_ray_tri_epsilon_v3(ray->origin, ray->direction, tri_cos[0], tri_cos[1], tri_cos[2], &dist, uv, ray->radius) : isect_ray_tri_v3(ray->origin, ray->direction, tri_cos[0], tri_cos[1], tri_cos[2], &dist, uv)); if (isect && dist < hit->dist) { hit->dist = dist; hit->index = index; copy_v3_v3(hit->no, ltri[0]->f->no); madd_v3_v3v3fl(hit->co, ray->origin, ray->direction, dist); copy_v2_v2(bmcb_data->uv, uv); } }
static void bmbvh_find_face_closest_cb(void *userdata, int index, const float co[3], BVHTreeNearest *hit) { struct FaceSearchUserData *bmcb_data = userdata; const BMLoop **ltri = bmcb_data->looptris[index]; const float dist_max_sq = bmcb_data->dist_max_sq; const float *tri_cos[3]; bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage); float co_close[3]; closest_on_tri_to_point_v3(co_close, co, UNPACK3(tri_cos)); const float dist_sq = len_squared_v3v3(co, co_close); if (dist_sq < hit->dist_sq && dist_sq < dist_max_sq) { /* XXX, normal ignores cage */ copy_v3_v3(hit->no, ltri[0]->f->no); hit->dist_sq = dist_sq; hit->index = index; } }
static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float co[3], BVHTreeNearest *hit) { struct VertSearchUserData *bmcb_data = userdata; const BMLoop **ltri = bmcb_data->looptris[index]; const float dist_max_sq = bmcb_data->dist_max_sq; int i; const float *tri_cos[3]; bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage); for (i = 0; i < 3; i++) { const float dist_sq = len_squared_v3v3(co, tri_cos[i]); if (dist_sq < hit->dist_sq && dist_sq < dist_max_sq) { copy_v3_v3(hit->co, tri_cos[i]); /* XXX, normal ignores cage */ copy_v3_v3(hit->no, ltri[i]->v->no); hit->dist_sq = dist_sq; hit->index = index; bmcb_data->index_tri = i; } } }