BLI_kdopbvh: Use distance for BLI_bvhtree_ray_cast_all
authorCampbell Barton <ideasman42@gmail.com>
Wed, 11 May 2016 04:33:49 +0000 (14:33 +1000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 11 May 2016 05:01:27 +0000 (15:01 +1000)
Pass distance argument so its possible to limit the range we get all hits from.

Other changes:

- Use boundbox test before calling callback, avoids redundant calls.
- Remove meaningless return value.
- Add doc string, explaining purpose of this function.

source/blender/blenlib/BLI_kdopbvh.h
source/blender/blenlib/intern/BLI_kdopbvh.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/transform/transform_snap.c

index a884f5ccaf4a6da3570873fd4068b43875ebde4e..fb8c2520e67bb9e3d0ed855ae5ca6602013fc987 100644 (file)
@@ -154,12 +154,12 @@ int BLI_bvhtree_ray_cast(
         BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit,
         BVHTree_RayCastCallback callback, void *userdata);
 
-int BLI_bvhtree_ray_cast_all_ex(
-        BVHTree *tree, const float co[3], const float dir[3], float radius,
+void BLI_bvhtree_ray_cast_all_ex(
+        BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist,
         BVHTree_RayCastCallback callback, void *userdata,
         int flag);
-int BLI_bvhtree_ray_cast_all(
-        BVHTree *tree, const float co[3], const float dir[3], float radius,
+void BLI_bvhtree_ray_cast_all(
+        BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist,
         BVHTree_RayCastCallback callback, void *userdata);
 
 float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]);
index c802dcb82f7602339ac7cfefe818a29c82aac3f9..5f64c137ce66ae5491dbfb5104d218c009fe8eea 100644 (file)
@@ -1643,7 +1643,9 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
         * before calling the ray-primitive functions */
        /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
        float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) : ray_nearest_hit(data, node->bv);
-       if (dist >= data->hit.dist) return;
+       if (dist >= data->hit.dist) {
+               return;
+       }
 
        if (node->totnode == 0) {
                if (data->callback) {
@@ -1670,6 +1672,9 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
        }
 }
 
+/**
+ * A version of #dfs_raycast with minor changes to reset the index & dist each ray cast.
+ */
 static void dfs_raycast_all(BVHRayCastData *data, BVHNode *node)
 {
        int i;
@@ -1678,18 +1683,16 @@ static void dfs_raycast_all(BVHRayCastData *data, BVHNode *node)
         * before calling the ray-primitive functions */
        /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
        float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) : ray_nearest_hit(data, node->bv);
+       if (dist >= data->hit.dist) {
+               return;
+       }
 
        if (node->totnode == 0) {
-               if (data->callback) {
-                       data->hit.index = -1;
-                       data->hit.dist = BVH_RAYCAST_DIST_MAX;
-                       data->callback(data->userdata, node->index, &data->ray, &data->hit);
-               }
-               else {
-                       data->hit.index = node->index;
-                       data->hit.dist  = dist;
-                       madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist);
-               }
+               /* no need to check for 'data->callback' (using 'all' only makes sense with a callback). */
+               dist = data->hit.dist;
+               data->callback(data->userdata, node->index, &data->ray, &data->hit);
+               data->hit.index = -1;
+               data->hit.dist = dist;
        }
        else {
                /* pick loop direction to dive into the tree (based on ray direction and split axis) */
@@ -1840,9 +1843,14 @@ float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], cons
 
 /**
  * Calls the callback for every ray intersection
+ *
+ * \note Using a \a callback which resets or never sets the #BVHTreeRayHit index & dist works too,
+ * however using this function means existing generic callbacks can be used from custom callbacks without
+ * having to handle resetting the hit beforehand.
+ * It also avoid redundant argument and return value which aren't meaningful when collecting multiple hits.
  */
-int BLI_bvhtree_ray_cast_all_ex(
-        BVHTree *tree, const float co[3], const float dir[3], float radius,
+void BLI_bvhtree_ray_cast_all_ex(
+        BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist,
         BVHTree_RayCastCallback callback, void *userdata,
         int flag)
 {
@@ -1850,6 +1858,7 @@ int BLI_bvhtree_ray_cast_all_ex(
        BVHNode *root = tree->nodes[tree->totleaf];
 
        BLI_ASSERT_UNIT_V3(dir);
+       BLI_assert(callback != NULL);
 
        data.tree = tree;
 
@@ -1863,20 +1872,18 @@ int BLI_bvhtree_ray_cast_all_ex(
        bvhtree_ray_cast_data_precalc(&data, flag);
 
        data.hit.index = -1;
-       data.hit.dist = BVH_RAYCAST_DIST_MAX;
+       data.hit.dist = hit_dist;
 
        if (root) {
                dfs_raycast_all(&data, root);
        }
-
-       return data.hit.index;
 }
 
-int BLI_bvhtree_ray_cast_all(
-        BVHTree *tree, const float co[3], const float dir[3], float radius,
+void BLI_bvhtree_ray_cast_all(
+        BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist,
         BVHTree_RayCastCallback callback, void *userdata)
 {
-       return BLI_bvhtree_ray_cast_all_ex(tree, co, dir, radius, callback, userdata, BVH_RAYCAST_DEFAULT);
+       BLI_bvhtree_ray_cast_all_ex(tree, co, dir, radius, hit_dist, callback, userdata, BVH_RAYCAST_DEFAULT);
 }
 
 
index 2ae1254f9e675ec05974b059319f26d447314769..3da3a451d66b04f05165a9aeddc058e2fe71a90c 100644 (file)
@@ -4111,7 +4111,9 @@ static bool shape_cut_test_point(PEData *data, ParticleCacheKey *key)
        userdata.bvhdata = data->shape_bvh;
        userdata.num_hits = 0;
        
-       BLI_bvhtree_ray_cast_all(shape_bvh->tree, key->co, dir, 0.0f, point_inside_bvh_cb, &userdata);
+       BLI_bvhtree_ray_cast_all(
+               shape_bvh->tree, key->co, dir, 0.0f, BVH_RAYCAST_DIST_MAX,
+               point_inside_bvh_cb, &userdata);
        
        /* for any point inside a watertight mesh the number of hits is uneven */
        return (userdata.num_hits % 2) == 1;
index eb601db358faa05b5ef3680afb12bd41b9945e59..bcbe1f582b7dd17ee983975db771b7f908b99302 100644 (file)
@@ -1486,7 +1486,7 @@ static bool peelDerivedMesh(
                                data.depth_peels = depth_peels;
 
                                BLI_bvhtree_ray_cast_all(
-                                       data.bvhdata.tree, ray_start_local, ray_normal_local, 0.0f,
+                                       data.bvhdata.tree, ray_start_local, ray_normal_local, 0.0f, BVH_RAYCAST_DIST_MAX,
                                        peelRayCast_cb, &data);
                        }
 
@@ -1538,7 +1538,7 @@ static bool peelEditMesh(
                                data.depth_peels = depth_peels;
 
                                BLI_bvhtree_ray_cast_all(
-                                       data.bvhdata.tree, ray_start_local, ray_normal_local, 0.0f,
+                                       data.bvhdata.tree, ray_start_local, ray_normal_local, 0.0f, BVH_RAYCAST_DIST_MAX,
                                        peelEditMeshRayCast_cb, &data);
                        }