PyAPI: Change ray_cast to fix & improve behavior
- It wasn't possible to know when Object.ray_cast was successful in the case when it hit a face with no original index. - Take (ray_start, ray_direction) vectors. - Take an optional distance argument. - Scene/Object.ray_cast now use matching arguments & return values. See D1650 (own patch)
This commit is contained in:
parent
e16d39b793
commit
08fb55eea2
Notes:
blender-bot
2023-02-14 10:21:11 +01:00
Referenced by issue #53714, Object.raycast() does not detect intersections where it should
|
@ -315,8 +315,10 @@ static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt)
|
|||
return index_mp_to_orig ? index_mp_to_orig[lt->poly] : lt->poly;
|
||||
}
|
||||
|
||||
static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start[3], float ray_end[3],
|
||||
float r_location[3], float r_normal[3], int *index)
|
||||
static void rna_Object_ray_cast(
|
||||
Object *ob, ReportList *reports,
|
||||
float origin[3], float direction[3], float distance,
|
||||
int *r_success, float r_location[3], float r_normal[3], int *r_index)
|
||||
{
|
||||
BVHTreeFromMesh treeData = {NULL};
|
||||
|
||||
|
@ -331,33 +333,41 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start
|
|||
/* may fail if the mesh has no faces, in that case the ray-cast misses */
|
||||
if (treeData.tree != NULL) {
|
||||
BVHTreeRayHit hit;
|
||||
float ray_nor[3], dist;
|
||||
sub_v3_v3v3(ray_nor, ray_end, ray_start);
|
||||
|
||||
dist = hit.dist = normalize_v3(ray_nor);
|
||||
hit.index = -1;
|
||||
hit.dist = distance;
|
||||
|
||||
if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit,
|
||||
normalize_v3(direction);
|
||||
|
||||
|
||||
if (BLI_bvhtree_ray_cast(treeData.tree, origin, direction, 0.0f, &hit,
|
||||
treeData.raycast_callback, &treeData) != -1)
|
||||
{
|
||||
if (hit.dist <= dist) {
|
||||
if (hit.dist <= distance) {
|
||||
*r_success = true;
|
||||
|
||||
copy_v3_v3(r_location, hit.co);
|
||||
copy_v3_v3(r_normal, hit.no);
|
||||
*index = dm_looptri_to_poly_index(ob->derivedFinal, &treeData.looptri[hit.index]);
|
||||
free_bvhtree_from_mesh(&treeData);
|
||||
return;
|
||||
*r_index = dm_looptri_to_poly_index(ob->derivedFinal, &treeData.looptri[hit.index]);
|
||||
|
||||
goto finally;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*r_success = false;
|
||||
|
||||
zero_v3(r_location);
|
||||
zero_v3(r_normal);
|
||||
*index = -1;
|
||||
*r_index = -1;
|
||||
|
||||
finally:
|
||||
free_bvhtree_from_mesh(&treeData);
|
||||
}
|
||||
|
||||
static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, float point_co[3], float max_dist,
|
||||
float n_location[3], float n_normal[3], int *index)
|
||||
static void rna_Object_closest_point_on_mesh(
|
||||
Object *ob, ReportList *reports, float origin[3], float distance,
|
||||
int *r_success, float r_location[3], float r_normal[3], int *r_index)
|
||||
{
|
||||
BVHTreeFromMesh treeData = {NULL};
|
||||
|
||||
|
@ -379,20 +389,26 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl
|
|||
BVHTreeNearest nearest;
|
||||
|
||||
nearest.index = -1;
|
||||
nearest.dist_sq = max_dist * max_dist;
|
||||
nearest.dist_sq = distance * distance;
|
||||
|
||||
if (BLI_bvhtree_find_nearest(treeData.tree, point_co, &nearest, treeData.nearest_callback, &treeData) != -1) {
|
||||
copy_v3_v3(n_location, nearest.co);
|
||||
copy_v3_v3(n_normal, nearest.no);
|
||||
*index = dm_looptri_to_poly_index(ob->derivedFinal, &treeData.looptri[nearest.index]);
|
||||
free_bvhtree_from_mesh(&treeData);
|
||||
return;
|
||||
if (BLI_bvhtree_find_nearest(treeData.tree, origin, &nearest, treeData.nearest_callback, &treeData) != -1) {
|
||||
*r_success = true;
|
||||
|
||||
copy_v3_v3(r_location, nearest.co);
|
||||
copy_v3_v3(r_normal, nearest.no);
|
||||
*r_index = dm_looptri_to_poly_index(ob->derivedFinal, &treeData.looptri[nearest.index]);
|
||||
|
||||
goto finally;
|
||||
}
|
||||
}
|
||||
|
||||
zero_v3(n_location);
|
||||
zero_v3(n_normal);
|
||||
*index = -1;
|
||||
*r_success = false;
|
||||
|
||||
zero_v3(r_location);
|
||||
zero_v3(r_normal);
|
||||
*r_index = -1;
|
||||
|
||||
finally:
|
||||
free_bvhtree_from_mesh(&treeData);
|
||||
}
|
||||
|
||||
|
@ -593,12 +609,15 @@ void RNA_api_object(StructRNA *srna)
|
|||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
|
||||
/* ray start and end */
|
||||
parm = RNA_def_float_vector(func, "start", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
parm = RNA_def_float_vector(func, "end", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
parm = RNA_def_float_vector(func, "direction", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
RNA_def_float(func, "distance", FLT_MAX, 0.0, FLT_MAX, "", "Maximum distance", 0.0, FLT_MAX);
|
||||
|
||||
/* return location and normal */
|
||||
parm = RNA_def_boolean(func, "result", 0, "", "");
|
||||
RNA_def_function_output(func, parm);
|
||||
parm = RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location",
|
||||
"The hit location of this ray cast", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_THICK_WRAP);
|
||||
|
@ -607,8 +626,7 @@ void RNA_api_object(StructRNA *srna)
|
|||
"The face normal at the ray cast hit location", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_THICK_WRAP);
|
||||
RNA_def_function_output(func, parm);
|
||||
|
||||
parm = RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when no intersection is found", 0, 0);
|
||||
parm = RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when original data isn't available", 0, 0);
|
||||
RNA_def_function_output(func, parm);
|
||||
|
||||
/* Nearest Point */
|
||||
|
@ -617,12 +635,14 @@ void RNA_api_object(StructRNA *srna)
|
|||
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||
|
||||
/* location of point for test and max distance */
|
||||
parm = RNA_def_float_vector(func, "point", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
/* default is sqrt(FLT_MAX) */
|
||||
RNA_def_float(func, "max_dist", 1.844674352395373e+19, 0.0, FLT_MAX, "", "", 0.0, FLT_MAX);
|
||||
RNA_def_float(func, "distance", 1.844674352395373e+19, 0.0, FLT_MAX, "", "Maximum distance", 0.0, FLT_MAX);
|
||||
|
||||
/* return location and normal */
|
||||
parm = RNA_def_boolean(func, "result", 0, "", "");
|
||||
RNA_def_function_output(func, parm);
|
||||
parm = RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location",
|
||||
"The location on the object closest to the point", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_THICK_WRAP);
|
||||
|
@ -632,7 +652,7 @@ void RNA_api_object(StructRNA *srna)
|
|||
RNA_def_property_flag(parm, PROP_THICK_WRAP);
|
||||
RNA_def_function_output(func, parm);
|
||||
|
||||
parm = RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when no closest point is found", 0, 0);
|
||||
parm = RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when original data isn't available", 0, 0);
|
||||
RNA_def_function_output(func, parm);
|
||||
|
||||
/* View */
|
||||
|
|
|
@ -137,31 +137,28 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, int previe
|
|||
}
|
||||
}
|
||||
|
||||
static void rna_Scene_ray_cast(Scene *scene, float ray_start[3], float ray_end[3],
|
||||
int *r_success, Object **r_ob, float r_obmat[16],
|
||||
float r_location[3], float r_normal[3])
|
||||
static void rna_Scene_ray_cast(
|
||||
Scene *scene, float origin[3], float direction[3], float ray_dist,
|
||||
int *r_success, float r_location[3], float r_normal[3], int *r_index,
|
||||
Object **r_ob, float r_obmat[16])
|
||||
{
|
||||
float ray_nor[3];
|
||||
float ray_dist;
|
||||
|
||||
sub_v3_v3v3(ray_nor, ray_end, ray_start);
|
||||
ray_dist = normalize_v3(ray_nor);
|
||||
normalize_v3(direction);
|
||||
|
||||
if (snapObjectsRayEx(
|
||||
scene, NULL, NULL, NULL, NULL,
|
||||
NULL, SNAP_ALL, SCE_SNAP_MODE_FACE,
|
||||
ray_start, ray_nor, &ray_dist,
|
||||
r_location, r_normal, NULL, NULL,
|
||||
origin, direction, &ray_dist,
|
||||
r_location, r_normal, NULL, r_index,
|
||||
r_ob, (float(*)[4])r_obmat))
|
||||
{
|
||||
*r_success = true;
|
||||
}
|
||||
else {
|
||||
*r_success = false;
|
||||
|
||||
unit_m4((float(*)[4])r_obmat);
|
||||
zero_v3(r_location);
|
||||
zero_v3(r_normal);
|
||||
|
||||
*r_success = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -231,18 +228,15 @@ void RNA_api_scene(StructRNA *srna)
|
|||
RNA_def_function_ui_description(func, "Cast a ray onto in object space");
|
||||
|
||||
/* ray start and end */
|
||||
parm = RNA_def_float_vector(func, "start", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
parm = RNA_def_float_vector(func, "origin", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
parm = RNA_def_float_vector(func, "end", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
parm = RNA_def_float_vector(func, "direction", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_REQUIRED);
|
||||
RNA_def_float(func, "distance", FLT_MAX, 0.0, FLT_MAX, "", "Maximum distance", 0.0, FLT_MAX);
|
||||
|
||||
/* return location and normal */
|
||||
parm = RNA_def_boolean(func, "result", 0, "", "");
|
||||
RNA_def_function_output(func, parm);
|
||||
parm = RNA_def_pointer(func, "object", "Object", "", "Ray cast object");
|
||||
RNA_def_function_output(func, parm);
|
||||
parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
|
||||
RNA_def_function_output(func, parm);
|
||||
parm = RNA_def_float_vector(func, "location", 3, NULL, -FLT_MAX, FLT_MAX, "Location",
|
||||
"The hit location of this ray cast", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_THICK_WRAP);
|
||||
|
@ -251,6 +245,12 @@ void RNA_api_scene(StructRNA *srna)
|
|||
"The face normal at the ray cast hit location", -1e4, 1e4);
|
||||
RNA_def_property_flag(parm, PROP_THICK_WRAP);
|
||||
RNA_def_function_output(func, parm);
|
||||
parm = RNA_def_int(func, "index", 0, 0, 0, "", "The face index, -1 when original data isn't available", 0, 0);
|
||||
RNA_def_function_output(func, parm);
|
||||
parm = RNA_def_pointer(func, "object", "Object", "", "Ray cast object");
|
||||
RNA_def_function_output(func, parm);
|
||||
parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
|
||||
RNA_def_function_output(func, parm);
|
||||
|
||||
#ifdef WITH_COLLADA
|
||||
/* don't remove this, as COLLADA exporting cannot be done through operators in render() callback. */
|
||||
|
|
Loading…
Reference in New Issue