Split ray_face_intersection into quad/tri versions
Since many callers only need a single triangle
This commit is contained in:
@@ -97,14 +97,15 @@ void BKE_pbvh_raycast(
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
bool original);
|
||||
|
||||
bool BKE_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float *dist);
|
||||
bool BKE_pbvh_node_raycast(
|
||||
PBVH *bvh, PBVHNode *node, float (*origco)[3], int use_origco,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float *dist);
|
||||
|
||||
bool BKE_pbvh_bmesh_node_raycast_detail(
|
||||
PBVHNode *node,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float *detail, float *dist);
|
||||
float *dist, float *r_detail);
|
||||
|
||||
/* for orthographic cameras, project the far away ray segment points to the root node so
|
||||
* we can have better precision. */
|
||||
|
||||
@@ -1503,18 +1503,17 @@ void BKE_pbvh_raycast(
|
||||
BKE_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
|
||||
}
|
||||
|
||||
bool ray_face_intersection(const float ray_start[3],
|
||||
const float ray_normal[3],
|
||||
const float t0[3], const float t1[3],
|
||||
const float t2[3], const float t3[3],
|
||||
float *fdist)
|
||||
bool ray_face_intersection_quad(
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
const float t0[3], const float t1[3], const float t2[3], const float t3[3],
|
||||
float *dist)
|
||||
{
|
||||
float dist;
|
||||
float dist_test;
|
||||
|
||||
if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist, NULL, 0.1f) && dist < *fdist) ||
|
||||
(t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
|
||||
if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist_test, NULL, 0.1f) && (dist_test < *dist)) ||
|
||||
(isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist_test, NULL, 0.1f) && (dist_test < *dist)))
|
||||
{
|
||||
*fdist = dist;
|
||||
*dist = dist_test;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -1522,10 +1521,27 @@ bool ray_face_intersection(const float ray_start[3],
|
||||
}
|
||||
}
|
||||
|
||||
static bool pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
|
||||
float (*origco)[3],
|
||||
const float ray_start[3],
|
||||
const float ray_normal[3], float *dist)
|
||||
bool ray_face_intersection_tri(
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
const float t0[3], const float t1[3], const float t2[3],
|
||||
float *dist)
|
||||
{
|
||||
float dist_test;
|
||||
|
||||
if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist_test, NULL, 0.1f) && (dist_test < *dist))) {
|
||||
*dist = dist_test;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool pbvh_faces_node_raycast(
|
||||
PBVH *bvh, const PBVHNode *node,
|
||||
float (*origco)[3],
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float *dist)
|
||||
{
|
||||
const MVert *vert = bvh->verts;
|
||||
const MLoop *mloop = bvh->mloop;
|
||||
@@ -1542,21 +1558,21 @@ static bool pbvh_faces_node_raycast(PBVH *bvh, const PBVHNode *node,
|
||||
|
||||
if (origco) {
|
||||
/* intersect with backuped original coordinates */
|
||||
hit |= ray_face_intersection(ray_start, ray_normal,
|
||||
origco[face_verts[0]],
|
||||
origco[face_verts[1]],
|
||||
origco[face_verts[2]],
|
||||
NULL,
|
||||
dist);
|
||||
hit |= ray_face_intersection_tri(
|
||||
ray_start, ray_normal,
|
||||
origco[face_verts[0]],
|
||||
origco[face_verts[1]],
|
||||
origco[face_verts[2]],
|
||||
dist);
|
||||
}
|
||||
else {
|
||||
/* intersect with current coordinates */
|
||||
hit |= ray_face_intersection(ray_start, ray_normal,
|
||||
vert[mloop[lt->tri[0]].v].co,
|
||||
vert[mloop[lt->tri[1]].v].co,
|
||||
vert[mloop[lt->tri[2]].v].co,
|
||||
NULL,
|
||||
dist);
|
||||
hit |= ray_face_intersection_tri(
|
||||
ray_start, ray_normal,
|
||||
vert[mloop[lt->tri[0]].v].co,
|
||||
vert[mloop[lt->tri[1]].v].co,
|
||||
vert[mloop[lt->tri[2]].v].co,
|
||||
dist);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1592,20 +1608,22 @@ static bool pbvh_grids_node_raycast(
|
||||
}
|
||||
|
||||
if (origco) {
|
||||
hit |= ray_face_intersection(ray_start, ray_normal,
|
||||
origco[y * gridsize + x],
|
||||
origco[y * gridsize + x + 1],
|
||||
origco[(y + 1) * gridsize + x + 1],
|
||||
origco[(y + 1) * gridsize + x],
|
||||
dist);
|
||||
hit |= ray_face_intersection_quad(
|
||||
ray_start, ray_normal,
|
||||
origco[y * gridsize + x],
|
||||
origco[y * gridsize + x + 1],
|
||||
origco[(y + 1) * gridsize + x + 1],
|
||||
origco[(y + 1) * gridsize + x],
|
||||
dist);
|
||||
}
|
||||
else {
|
||||
hit |= ray_face_intersection(ray_start, ray_normal,
|
||||
CCG_grid_elem_co(&bvh->gridkey, grid, x, y),
|
||||
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y),
|
||||
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1),
|
||||
CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1),
|
||||
dist);
|
||||
hit |= ray_face_intersection_quad(
|
||||
ray_start, ray_normal,
|
||||
CCG_grid_elem_co(&bvh->gridkey, grid, x, y),
|
||||
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y),
|
||||
CCG_grid_elem_co(&bvh->gridkey, grid, x + 1, y + 1),
|
||||
CCG_grid_elem_co(&bvh->gridkey, grid, x, y + 1),
|
||||
dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1629,15 +1647,18 @@ bool BKE_pbvh_node_raycast(
|
||||
|
||||
switch (bvh->type) {
|
||||
case PBVH_FACES:
|
||||
hit |= pbvh_faces_node_raycast(bvh, node, origco,
|
||||
ray_start, ray_normal, dist);
|
||||
hit |= pbvh_faces_node_raycast(
|
||||
bvh, node, origco,
|
||||
ray_start, ray_normal, dist);
|
||||
break;
|
||||
case PBVH_GRIDS:
|
||||
hit |= pbvh_grids_node_raycast(bvh, node, origco,
|
||||
ray_start, ray_normal, dist);
|
||||
hit |= pbvh_grids_node_raycast(
|
||||
bvh, node, origco,
|
||||
ray_start, ray_normal, dist);
|
||||
break;
|
||||
case PBVH_BMESH:
|
||||
hit = pbvh_bmesh_node_raycast(node, ray_start, ray_normal, dist, use_origco);
|
||||
hit = pbvh_bmesh_node_raycast(
|
||||
node, ray_start, ray_normal, dist, use_origco);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1358,11 +1358,12 @@ bool pbvh_bmesh_node_raycast(
|
||||
int i;
|
||||
for (i = 0; i < node->bm_tot_ortri; i++) {
|
||||
const int *t = node->bm_ortri[i];
|
||||
hit |= ray_face_intersection(ray_start, ray_normal,
|
||||
node->bm_orco[t[0]],
|
||||
node->bm_orco[t[1]],
|
||||
node->bm_orco[t[2]],
|
||||
NULL, dist);
|
||||
hit |= ray_face_intersection_tri(
|
||||
ray_start, ray_normal,
|
||||
node->bm_orco[t[0]],
|
||||
node->bm_orco[t[1]],
|
||||
node->bm_orco[t[2]],
|
||||
dist);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1376,11 +1377,12 @@ bool pbvh_bmesh_node_raycast(
|
||||
BMVert *v_tri[3];
|
||||
|
||||
BM_face_as_array_vert_tri(f, v_tri);
|
||||
hit |= ray_face_intersection(ray_start, ray_normal,
|
||||
v_tri[0]->co,
|
||||
v_tri[1]->co,
|
||||
v_tri[2]->co,
|
||||
NULL, dist);
|
||||
hit |= ray_face_intersection_tri(
|
||||
ray_start, ray_normal,
|
||||
v_tri[0]->co,
|
||||
v_tri[1]->co,
|
||||
v_tri[2]->co,
|
||||
dist);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1391,7 +1393,7 @@ bool pbvh_bmesh_node_raycast(
|
||||
bool BKE_pbvh_bmesh_node_raycast_detail(
|
||||
PBVHNode *node,
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
float *detail, float *dist)
|
||||
float *dist, float *r_detail)
|
||||
{
|
||||
GSetIterator gs_iter;
|
||||
bool hit = false;
|
||||
@@ -1408,12 +1410,12 @@ bool BKE_pbvh_bmesh_node_raycast_detail(
|
||||
BMVert *v_tri[3];
|
||||
bool hit_local;
|
||||
BM_face_as_array_vert_tri(f, v_tri);
|
||||
hit_local = ray_face_intersection(
|
||||
hit_local = ray_face_intersection_tri(
|
||||
ray_start, ray_normal,
|
||||
v_tri[0]->co,
|
||||
v_tri[1]->co,
|
||||
v_tri[2]->co,
|
||||
NULL, dist);
|
||||
dist);
|
||||
|
||||
if (hit_local) {
|
||||
f_hit = f;
|
||||
@@ -1431,7 +1433,7 @@ bool BKE_pbvh_bmesh_node_raycast_detail(
|
||||
len3 = len_squared_v3v3(v_tri[2]->co, v_tri[0]->co);
|
||||
|
||||
/* detail returned will be set to the maximum allowed size, so take max here */
|
||||
*detail = sqrtf(max_fff(len1, len2, len3));
|
||||
*r_detail = sqrtf(max_fff(len1, len2, len3));
|
||||
}
|
||||
|
||||
return hit;
|
||||
|
||||
@@ -176,10 +176,14 @@ void BB_expand_with_bb(BB *bb, BB *bb2);
|
||||
void BBC_update_centroid(BBC *bbc);
|
||||
int BB_widest_axis(const BB *bb);
|
||||
void pbvh_grow_nodes(PBVH *bvh, int totnode);
|
||||
bool ray_face_intersection(
|
||||
bool ray_face_intersection_quad(
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
const float *t0, const float *t1, const float *t2, const float *t3,
|
||||
float *r_dist);
|
||||
bool ray_face_intersection_tri(
|
||||
const float ray_start[3], const float ray_normal[3],
|
||||
const float *t0, const float *t1, const float *t2,
|
||||
const float *t3, float *fdist);
|
||||
float *r_dist);
|
||||
void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes, int totnode, int flag);
|
||||
|
||||
/* pbvh_bmesh.c */
|
||||
|
||||
@@ -4132,7 +4132,7 @@ static void sculpt_raycast_detail_cb(PBVHNode *node, void *data_v, float *tmin)
|
||||
if (BKE_pbvh_node_get_tmin(node) < *tmin) {
|
||||
SculptDetailRaycastData *srd = data_v;
|
||||
if (BKE_pbvh_bmesh_node_raycast_detail(node, srd->ray_start, srd->ray_normal,
|
||||
&srd->detail, &srd->dist))
|
||||
&srd->dist, &srd->detail))
|
||||
{
|
||||
srd->hit = 1;
|
||||
*tmin = srd->dist;
|
||||
|
||||
Reference in New Issue
Block a user