BMFace *BKE_bmbvh_find_face_segment(BMBVHTree *bmtree, const float co_a[3], const float co_b[3], float *r_fac, float r_hitout[3], float r_cagehit[3]) { BVHTreeRayHit hit; struct SegmentUserData bmcb_data; const float dist = len_v3v3(co_a, co_b); float dir[3]; if (bmtree->cos_cage) BLI_assert(!(bmtree->bm->elem_index_dirty & BM_VERT)); sub_v3_v3v3(dir, co_b, co_a); hit.dist = dist; hit.index = -1; /* ok to leave 'uv' uninitialized */ bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->looptris; bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage; bmcb_data.co_a = co_a; bmcb_data.co_b = co_b; BLI_bvhtree_ray_cast(bmtree->tree, co_a, dir, 0.0f, &hit, bmbvh_find_face_segment_cb, &bmcb_data); if (hit.index != -1 && hit.dist != dist) { /* duplicate of BKE_bmbvh_ray_cast() */ if (r_hitout) { if (bmtree->flag & BMBVH_RETURN_ORIG) { BMLoop **ltri = bmtree->looptris[hit.index]; interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, bmcb_data.uv); } else { copy_v3_v3(r_hitout, hit.co); } if (r_cagehit) { copy_v3_v3(r_cagehit, hit.co); } } /* end duplicate */ if (r_fac) { *r_fac = hit.dist / dist; } return bmtree->looptris[hit.index][0]->f; } return NULL; }
BMFace *BKE_bmbvh_ray_cast(BMBVHTree *bmtree, const float co[3], const float dir[3], const float radius, float *r_dist, float r_hitout[3], float r_cagehit[3]) { BVHTreeRayHit hit; struct RayCastUserData bmcb_data; const float dist = r_dist ? *r_dist : FLT_MAX; if (bmtree->cos_cage) BLI_assert(!(bmtree->bm->elem_index_dirty & BM_VERT)); hit.dist = dist; hit.index = -1; /* ok to leave 'uv' uninitialized */ bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->looptris; bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage; BLI_bvhtree_ray_cast(bmtree->tree, co, dir, radius, &hit, bmbvh_ray_cast_cb, &bmcb_data); if (hit.index != -1 && hit.dist != dist) { if (r_hitout) { if (bmtree->flag & BMBVH_RETURN_ORIG) { BMLoop **ltri = bmtree->looptris[hit.index]; interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, bmcb_data.uv); } else { copy_v3_v3(r_hitout, hit.co); } if (r_cagehit) { copy_v3_v3(r_cagehit, hit.co); } } if (r_dist) { *r_dist = hit.dist; } return bmtree->looptris[hit.index][0]->f; } return NULL; }
static BMFace *bmbvh_ray_cast_handle_hit( BMBVHTree *bmtree, struct RayCastUserData *bmcb_data, const BVHTreeRayHit *hit, float *r_dist, float r_hitout[3], float r_cagehit[3]) { if (r_hitout) { if (bmtree->flag & BMBVH_RETURN_ORIG) { BMLoop **ltri = bmtree->looptris[hit->index]; interp_v3_v3v3v3_uv(r_hitout, ltri[0]->v->co, ltri[1]->v->co, ltri[2]->v->co, bmcb_data->uv); } else { copy_v3_v3(r_hitout, hit->co); } if (r_cagehit) { copy_v3_v3(r_cagehit, hit->co); } } if (r_dist) { *r_dist = hit->dist; } return bmtree->looptris[hit->index][0]->f; }