50#define MAX_TREETYPE 32
54# define KDOPBVH_THREAD_LEAF_THRESHOLD 0
56# define KDOPBVH_THREAD_LEAF_THRESHOLD 1024
93 (
sizeof(
void *) == 4 &&
sizeof(
BVHTree) <= 32),
97struct BVHOverlapData_Shared {
99 axis_t start_axis, stop_axis;
132#ifdef USE_KDOPBVH_WATERTIGHT
210 return (a <
b) ? a :
b;
215 return (
b < a) ? a :
b;
231 for (axis_iter =
tree->start_axis; axis_iter !=
tree->stop_axis; axis_iter++) {
250 for (
i = lo;
i < hi;
i++) {
253 while ((j != lo) && (t->
bv[axis] < (a[j - 1])->bv[axis])) {
265 while (a[
i]->bv[axis] <
x->bv[axis]) {
269 while (
x->bv[axis] < a[j]->
bv[axis]) {
283 if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) {
284 if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
287 if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
293 if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
294 if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
309 while (end -
begin > 3) {
327 node->skip[0] =
left;
328 node->skip[1] = right;
350 float *bv = node->
bv;
359 for (k = 0; k < numpoints; k++) {
361 for (axis_iter =
tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
363 bv[2 * axis_iter] = std::min(newminmax, bv[2 * axis_iter]);
364 bv[(2 * axis_iter) + 1] = std::max(newminmax, bv[(2 * axis_iter) + 1]);
374 float newmin, newmax;
375 float *__restrict bv = node->
bv;
381 for (j = start; j < end; j++) {
382 const float *__restrict node_bv =
tree->nodes[j]->bv;
385 for (axis_iter =
tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
386 newmin = node_bv[(2 * axis_iter)];
387 bv[(2 * axis_iter)] = std::min(newmin, bv[(2 * axis_iter)]);
389 newmax = node_bv[(2 * axis_iter) + 1];
390 bv[(2 * axis_iter) + 1] = std::max(newmax, bv[(2 * axis_iter) + 1]);
401 float middle_point[3];
403 middle_point[0] = (bv[1]) - (bv[0]);
404 middle_point[1] = (bv[3]) - (bv[2]);
405 middle_point[2] = (bv[5]) - (bv[4]);
406 if (middle_point[0] > middle_point[1]) {
407 if (middle_point[0] > middle_point[2]) {
412 if (middle_point[1] > middle_point[2]) {
429 for (
i = 0;
i <
tree->tree_type;
i++) {
431 for (axis_iter =
tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
433 node->
bv[(2 * axis_iter)] = std::min(node->
children[
i]->
bv[(2 * axis_iter)],
434 node->
bv[(2 * axis_iter)]);
437 node->
bv[(2 * axis_iter) + 1] = std::max(node->
children[
i]->
bv[(2 * axis_iter) + 1],
438 node->
bv[(2 * axis_iter) + 1]);
458 for (
i = 0;
i < depth;
i++) {
461 printf(
" - %d (%ld): ", node->
index, (
long int)(node -
tree->nodearray));
465 printf(
"%.3f ", node->
bv[axis_iter]);
469 for (
i = 0;
i <
tree->tree_type;
i++) {
478 printf(
"BVHTree Info: tree_type = %d, axis = %d, epsilon = %f\n",
482 printf(
"nodes = %d, branches = %d, leafs = %d\n",
486 printf(
"Memory per node = %ubytes\n",
490 printf(
"Total memory = %ubytes\n",
494 bvhtree_print_tree(
tree,
tree->nodes[
tree->leaf_num], 0);
501#ifdef USE_VERIFY_TREE
508 for (
i = 0;
i <
tree->leaf_num;
i++) {
509 if (
tree->nodes[
i]->parent ==
nullptr) {
510 printf(
"Leaf has no parent: %d\n",
i);
513 for (j = 0; j <
tree->tree_type; j++) {
514 if (
tree->nodes[
i]->parent->children[j] ==
tree->nodes[
i]) {
519 printf(
"Parent child relationship doesn't match: %d\n",
i);
526 for (
i = 0;
i <
tree->leaf_num;
i++) {
527 if (
tree->nodearray[
i].parent ==
nullptr) {
528 printf(
"Leaf has no parent: %d\n",
i);
531 for (j = 0; j <
tree->tree_type; j++) {
532 if (
tree->nodearray[
i].parent->children[j] == &
tree->nodearray[
i]) {
537 printf(
"Parent child relationship doesn't match: %d\n",
i);
543 printf(
"branches: %d, leafs: %d, total: %d\n",
576 for (
data->leafs_per_child[0] = 1;
data->leafs_per_child[0] <
data->leafs_num;
577 data->leafs_per_child[0] *=
data->tree_type)
582 data->branches_on_level[0] = 1;
584 for (depth = 1; (depth < 32) &&
data->leafs_per_child[depth - 1]; depth++) {
585 data->branches_on_level[depth] =
data->branches_on_level[depth - 1] *
data->tree_type;
586 data->leafs_per_child[depth] =
data->leafs_per_child[depth - 1] /
data->tree_type;
589 remain =
data->leafs_num -
data->leafs_per_child[1];
590 nnodes = (remain +
data->tree_type - 2) / (
data->tree_type - 1);
591 data->remain_leafs = remain + nnodes;
599 int min_leaf_index = child_index *
data->leafs_per_child[depth - 1];
600 if (min_leaf_index <= data->remain_leafs) {
601 return min_leaf_index;
603 if (
data->leafs_per_child[depth]) {
604 return data->leafs_num -
605 (
data->branches_on_level[depth - 1] - child_index) *
data->leafs_per_child[depth];
607 return data->remain_leafs;
642 return max_ii(1, (leafs + tree_type - 3) / (tree_type - 1));
659 const int partitions,
660 const int split_axis)
663 for (
i = 0;
i < partitions - 1;
i++) {
664 if (nth[
i] >= nth[partitions]) {
694 const int parent_level_index = j -
data->i;
714 nth_positions[0] = parent_leafs_begin;
715 nth_positions[
data->tree_type] = parent_leafs_end;
716 for (k = 1; k <
data->tree_type; k++) {
717 const int child_index = j *
data->tree_type +
data->tree_offset + k;
719 const int child_level_index = child_index -
data->first_of_next_level;
728 for (k = 0; k <
data->tree_type; k++) {
729 const int child_index = j *
data->tree_type +
data->tree_offset + k;
731 const int child_level_index = child_index -
data->first_of_next_level;
734 data->data,
data->depth + 1, child_level_index);
736 data->data,
data->depth + 1, child_level_index + 1);
738 if (child_leafs_end - child_leafs_begin > 1) {
739 parent->
children[k] = &
data->branches_array[child_index];
742 else if (child_leafs_end - child_leafs_begin == 1) {
743 parent->
children[k] =
data->leafs_array[child_leafs_begin];
778 const int tree_type =
tree->tree_type;
780 const int tree_offset = 2 -
tree->tree_type;
789 BVHNode *root = &branches_array[1];
794 if (leafs_num == 1) {
818 for (
i = 1, depth = 1;
i <= branches_num;
i =
i * tree_type + tree_offset, depth++) {
819 const int first_of_next_level =
i * tree_type + tree_offset;
821 const int i_stop =
min_ii(first_of_next_level, branches_num + 1);
826 cb_data.
depth = depth;
837 for (
int i_task =
i; i_task < i_stop; i_task++) {
862 epsilon =
max_ff(FLT_EPSILON, epsilon);
865 tree->epsilon = epsilon;
866 tree->tree_type = tree_type;
870 tree->start_axis = 0;
871 tree->stop_axis = 13;
873 else if (axis == 18) {
874 tree->start_axis = 7;
875 tree->stop_axis = 13;
877 else if (axis == 14) {
878 tree->start_axis = 0;
881 else if (axis == 8) {
882 tree->start_axis = 0;
885 else if (axis == 6) {
886 tree->start_axis = 0;
909 for (
i = 0;
i < numnodes;
i++) {
910 tree->nodearray[
i].bv = &
tree->nodebv[
i * axis];
911 tree->nodearray[
i].children = &
tree->nodechild[
i * tree_type];
947 for (
int i = 0;
i <
tree->branch_num;
i++) {
952 build_skip_links(
tree,
tree->nodes[
tree->leaf_num],
nullptr,
nullptr);
955#ifdef USE_VERIFY_TREE
956 bvhtree_verify(
tree);
967 for (axis_iter =
tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
969 node->
bv[(2 * axis_iter)] -= dist_corrected;
970 node->
bv[(2 * axis_iter) + 1] += dist_corrected;
993 BVHTree *
tree,
int index,
const float co[3],
const float co_moving[3],
int numpoints)
998 if (index >
tree->leaf_num) {
1002 node =
tree->nodearray + index;
1025 for (; index >= root; index--) {
1031 return tree->leaf_num;
1036 return tree->tree_type;
1041 return tree->epsilon;
1047 if (root !=
nullptr) {
1048 const float bb_min[3] = {root->
bv[0], root->
bv[2], root->
bv[4]};
1049 const float bb_max[3] = {root->
bv[1], root->
bv[3], root->
bv[5]};
1074 const float *bv1 = node1->
bv + (start_axis << 1);
1075 const float *bv2 = node2->
bv + (start_axis << 1);
1076 const float *bv1_end = node1->
bv + (stop_axis << 1);
1079 for (; bv1 != bv1_end; bv1 += 2, bv2 += 2) {
1080 if ((bv1[0] > bv2[1]) || (bv2[0] > bv1[1])) {
1092 const BVHOverlapData_Shared *
data = data_thread->
shared;
1112 for (j = 0; j <
data->tree2->tree_type; j++) {
1120 for (j = 0; j <
data->tree1->tree_type; j++) {
1136 BVHOverlapData_Shared *
data = data_thread->
shared;
1159 for (j = 0; j <
data->tree2->tree_type; j++) {
1167 for (j = 0; j <
data->tree1->tree_type; j++) {
1183 BVHOverlapData_Shared *
data = data_thread->
shared;
1198 if (!
data->callback ||
1211 for (j = 0; j < node2->
node_num; j++) {
1220 for (j = 0; j < node1->
node_num; j++) {
1235 if (
data->max_interactions) {
1238 else if (
data->shared->callback) {
1254 for (
int j =
i + 1; j < node->
node_num; j++) {
1268 for (
int j =
i + 1; j < node->
node_num; j++) {
1278 if (data_thread->
shared->callback) {
1288 return std::min<int>(
tree->tree_type,
tree->nodes[
tree->leaf_num]->node_num);
1296 BVHOverlapData_Shared *data_shared =
data->shared;
1298 const BVHNode *root1 = data_shared->tree1->nodes[data_shared->tree1->leaf_num];
1300 if (data_shared->use_self) {
1304 for (
int k = j + 1; k < root1->
node_num; k++) {
1309 const BVHNode *root2 = data_shared->tree2->nodes[data_shared->tree2->leaf_num];
1318 uint *r_overlap_num,
1322 const uint max_interactions,
1331 BLI_assert(overlap_pairs || max_interactions);
1333 BLI_assert(!use_self || (tree1 == tree2 && !max_interactions));
1336 const int thread_num = use_threading ? root_node_len : 1;
1340 BVHOverlapData_Shared data_shared;
1342 axis_t start_axis, stop_axis;
1346 (tree1->
axis == 18 || tree2->
axis == 18)))
1352 if (
UNLIKELY(use_self && tree1 != tree2)) {
1367 data_shared.tree1 = tree1;
1368 data_shared.tree2 = tree2;
1370 data_shared.stop_axis = stop_axis;
1371 data_shared.use_self = use_self;
1374 data_shared.callback = callback;
1375 data_shared.userdata = userdata;
1377 for (j = 0; j < thread_num; j++) {
1379 data[j].shared = &data_shared;
1381 data[j].max_interactions = use_self ? 0 : max_interactions;
1387 if (use_threading) {
1393 else if (use_self) {
1400 if (overlap_pairs) {
1401 for (j = 0; j < thread_num; j++) {
1407 for (j = 0; j < thread_num; j++) {
1413 *r_overlap_num =
uint(total);
1422 uint *r_overlap_num,
1438 uint *r_overlap_num,
1462 const float bb_min[3] = {bv[0], bv[2], bv[4]};
1463 const float bb_max[3] = {bv[1], bv[3], bv[5]};
1464 float bb_near[3], bb_far[3];
1484 for (
int j = 0; j <
data->tree->tree_type; j++) {
1498 if (
tree->leaf_num) {
1514 *r_intersect_num =
uint(total);
1529 const float *bv = node->
bv;
1532 for (
i = 0;
i != 3;
i++, bv += 2) {
1533 float val = proj[
i];
1534 val = std::max(bv[0], val);
1535 val = std::min(bv[1], val);
1546 if (
data->callback) {
1563 data->nearest.dist_sq)
1573 data->nearest.dist_sq)
1585 float nearest[3], dist_sq;
1587 if (dist_sq >=
data->nearest.dist_sq) {
1597 if (
data->callback) {
1611 if (dist_sq < data->nearest.dist_sq) {
1623 if (dist_sq < data->nearest.dist_sq) {
1655 data.callback = callback;
1656 data.userdata = userdata;
1658 for (axis_iter =
data.tree->start_axis; axis_iter !=
data.tree->stop_axis; axis_iter++) {
1663 memcpy(&
data.nearest, nearest,
sizeof(*nearest));
1666 data.nearest.index = -1;
1682 memcpy(nearest, &
data.nearest,
sizeof(*nearest));
1685 return data.nearest.index;
1707 if (co[0] > bv[0].
min && co[0] < bv[0].
max && co[1] > bv[1].
min && co[1] < bv[1].
max &&
1708 co[2] > bv[2].
min && co[2] < bv[2].
max)
1720 if (
data->callback) {
1721 const float dist_sq =
data->nearest.dist_sq;
1723 return (
data->nearest.dist_sq < dist_sq);
1757 const float dist_sq,
1768 data.callback = callback;
1769 data.userdata = userdata;
1770 data.nearest.index = -1;
1771 data.nearest.dist_sq = dist_sq;
1778 return data.nearest.index;
1795 float low = 0, upper =
data->hit.dist;
1797 for (
i = 0;
i != 3;
i++, bv += 2) {
1798 if (
data->ray_dot_axis[
i] == 0.0f) {
1800 if (
data->ray.origin[
i] < bv[0] -
data->ray.radius ||
1801 data->ray.origin[
i] > bv[1] +
data->ray.radius)
1807 float ll = (bv[0] -
data->ray.radius -
data->ray.origin[
i]) /
data->ray_dot_axis[
i];
1808 float lu = (bv[1] +
data->ray.radius -
data->ray.origin[
i]) /
data->ray_dot_axis[
i];
1810 if (
data->ray_dot_axis[
i] > 0.0f) {
1811 low = std::max(ll, low);
1812 upper = std::min(lu, upper);
1815 low = std::max(lu, low);
1816 upper = std::min(ll, upper);
1835 const float *bv = node->
bv;
1837 float t1x = (bv[
data->index[0]] -
data->ray.origin[0]) *
data->idot_axis[0];
1838 float t2x = (bv[
data->index[1]] -
data->ray.origin[0]) *
data->idot_axis[0];
1839 float t1y = (bv[
data->index[2]] -
data->ray.origin[1]) *
data->idot_axis[1];
1840 float t2y = (bv[
data->index[3]] -
data->ray.origin[1]) *
data->idot_axis[1];
1841 float t1z = (bv[
data->index[4]] -
data->ray.origin[2]) *
data->idot_axis[2];
1842 float t2z = (bv[
data->index[5]] -
data->ray.origin[2]) *
data->idot_axis[2];
1844 if ((t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) ||
1845 (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) ||
1846 (t1x >
data->hit.dist || t1y >
data->hit.dist || t1z >
data->hit.dist))
1850 return max_fff(t1x, t1y, t1z);
1862 if (dist >=
data->hit.dist) {
1867 if (
data->callback) {
1872 data->hit.dist = dist;
1903 if (dist >=
data->hit.dist) {
1909 dist =
data->hit.dist;
1911 data->hit.index = -1;
1912 data->hit.dist = dist;
1933 for (
i = 0;
i < 3;
i++) {
1936 if (
fabsf(
data->ray_dot_axis[
i]) < FLT_EPSILON) {
1937 data->ray_dot_axis[
i] = 0.0f;
1942 data->idot_axis[
i] = 1.0f /
data->ray_dot_axis[
i];
1945 data->index[2 *
i] =
data->idot_axis[
i] < 0.0f ? 1 : 0;
1946 data->index[2 *
i + 1] = 1 -
data->index[2 *
i];
1947 data->index[2 *
i] += 2 *
i;
1948 data->index[2 *
i + 1] += 2 *
i;
1951#ifdef USE_KDOPBVH_WATERTIGHT
1954 data->ray.isect_precalc = &
data->isect_precalc;
1957 data->ray.isect_precalc =
nullptr;
1980 data.callback = callback;
1981 data.userdata = userdata;
1985 data.ray.radius = radius;
1990 memcpy(&
data.hit, hit,
sizeof(*hit));
1993 data.hit.index = -1;
2003 memcpy(hit, &
data.hit,
sizeof(*hit));
2006 return data.hit.index;
2022 const float light_start[3],
2023 const float light_end[3],
2034 data.ray.radius = 0.0;
2065 data.callback = callback;
2066 data.userdata = userdata;
2070 data.ray.radius = radius;
2074 data.hit.index = -1;
2075 data.hit.dist = hit_dist;
2123 co[0] = node->
bv[0];
2124 co[1] = node->
bv[2];
2125 co[2] = node->
bv[4];
2133 if (dist_sq < data->radius_sq) {
2158 data.radius_sq = radius * radius;
2161 data.callback = callback;
2162 data.userdata = userdata;
2164 if (root !=
nullptr) {
2167 if (dist_sq <
data.radius_sq) {
2192 if (
data->callback) {
2201 data->closest_axis);
2213 data->closest_axis) <=
data->nearest.dist_sq)
2226 data->closest_axis) <=
data->nearest.dist_sq)
2239 if (
data->callback) {
2244 data->clip_plane_len,
2253 data->closest_axis);
2261 const float bb_min[3] = {bv[0], bv[2], bv[4]};
2262 const float bb_max[3] = {bv[1], bv[3], bv[5]};
2265 data->clip_plane,
data->clip_plane_len, bb_min, bb_max);
2269 data->nearest.dist_sq)
2284 const float bb_min[3] = {bv[0], bv[2], bv[4]};
2285 const float bb_max[3] = {bv[1], bv[3], bv[5]};
2288 data->clip_plane,
data->clip_plane_len, bb_min, bb_max);
2292 data->nearest.dist_sq)
2308 float projmat[4][4],
2311 float (*clip_plane)[4],
2318 if (root !=
nullptr) {
2320 sizeof(*
data) + (
sizeof(*clip_plane) *
size_t(
max_ii(1, clip_plane_len))));
2324 data->callback = callback;
2325 data->userdata = userdata;
2328# pragma GCC diagnostic push
2329# pragma GCC diagnostic ignored "-Warray-bounds"
2332 data->clip_plane_len = clip_plane_len;
2333 for (
int i = 0;
i < clip_plane_len;
i++) {
2338 data->clip_plane_len = 1;
2340 projmat,
nullptr,
nullptr,
nullptr,
nullptr,
data->clip_plane[0],
nullptr);
2343# pragma GCC diagnostic pop
2347 memcpy(&
data->nearest, nearest,
sizeof(*nearest));
2350 data->nearest.index = -1;
2354 const float bb_min[3] = {root->
bv[0], root->
bv[2], root->
bv[4]};
2355 const float bb_max[3] = {root->
bv[1], root->
bv[3], root->
bv[5]};
2358 data->clip_plane,
data->clip_plane_len, bb_min, bb_max);
2360 if (isect_type != 0 &&
2362 data->nearest.dist_sq)
2364 if (isect_type == 1) {
2374 memcpy(nearest, &
data->nearest,
sizeof(*nearest));
2377 return data->nearest.index;
#define BLI_array_alloca(arr, realsize)
#define BLI_assert_unreachable()
#define BLI_STATIC_ASSERT(a, msg)
A min-heap / priority queue ADT.
void BLI_heapsimple_free(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp) ATTR_NONNULL(1)
HeapSimple * BLI_heapsimple_new_ex(unsigned int reserve_num) ATTR_WARN_UNUSED_RESULT
float BLI_heapsimple_top_value(const HeapSimple *heap) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
void * BLI_heapsimple_pop_min(HeapSimple *heap) ATTR_NONNULL(1)
bool BLI_heapsimple_is_empty(const HeapSimple *heap) ATTR_NONNULL(1)
void BLI_heapsimple_insert(HeapSimple *heap, float value, void *ptr) ATTR_NONNULL(1)
static void bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(BVHNearestProjectedData *__restrict data, const BVHNode *node)
static void dfs_raycast_all(BVHRayCastData *data, BVHNode *node)
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
int * BLI_bvhtree_intersect_plane(const BVHTree *tree, float plane[4], uint *r_intersect_num)
int BLI_bvhtree_find_nearest_first(const BVHTree *tree, const float co[3], const float dist_sq, BVHTree_NearestPointCallback callback, void *userdata)
static void bvhtree_ray_cast_data_precalc(BVHRayCastData *data, int flag)
static void bvhtree_node_inflate(const BVHTree *tree, BVHNode *node, const float dist)
int BLI_bvhtree_get_tree_type(const BVHTree *tree)
void BLI_bvhtree_get_bounding_box(const BVHTree *tree, float r_bb_min[3], float r_bb_max[3])
static void heap_find_nearest_begin(BVHNearestData *data, BVHNode *root)
static void bvh_insertionsort(BVHNode **a, int lo, int hi, int axis)
#define KDOPBVH_THREAD_LEAF_THRESHOLD
static void non_recursive_bvh_div_nodes(const BVHTree *tree, BVHNode *branches_array, BVHNode **leafs_array, int leafs_num)
static void tree_overlap_traverse_self(BVHOverlapData_Thread *data_thread, const BVHNode *node)
static bool tree_intersect_plane_test(const float *bv, const float plane[4])
static void tree_overlap_traverse_cb(BVHOverlapData_Thread *data_thread, const BVHNode *node1, const BVHNode *node2)
static char get_largest_axis(const float *bv)
static void build_implicit_tree_helper(const BVHTree *tree, BVHBuildHelper *data)
static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node)
static bool tree_overlap_test(const BVHNode *node1, const BVHNode *node2, axis_t start_axis, axis_t stop_axis)
static bool tree_overlap_traverse_num(BVHOverlapData_Thread *data_thread, const BVHNode *node1, const BVHNode *node2)
void BLI_bvhtree_balance(BVHTree *tree)
static int bvh_partition(BVHNode **a, int lo, int hi, const BVHNode *x, int axis)
static void heap_find_nearest_inner(BVHNearestData *data, HeapSimple *heap, BVHNode *node)
void BLI_bvhtree_update_tree(BVHTree *tree)
static bool isect_aabb_v3(BVHNode *node, const float co[3])
MINLINE axis_t min_axis(axis_t a, axis_t b)
int BLI_bvhtree_find_nearest_projected(const BVHTree *tree, float projmat[4][4], float winsize[2], float mval[2], float(*clip_plane)[4], int clip_plane_len, BVHTreeNearest *nearest, BVHTree_NearestProjectedCallback 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])
static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
static float ray_nearest_hit(const BVHRayCastData *data, const float bv[6])
void BLI_bvhtree_ray_cast_all_ex(const BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist, BVHTree_RayCastCallback callback, void *userdata, int flag)
void BLI_bvhtree_free(BVHTree *tree)
static void dfs_range_query(RangeQueryData *data, BVHNode *node)
static void refit_kdop_hull(const BVHTree *tree, BVHNode *node, int start, int end)
static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *node)
static bool dfs_find_duplicate_fast_dfs(BVHNearestData *data, BVHNode *node)
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
static void non_recursive_bvh_div_nodes_task_cb(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict)
static void node_join(BVHTree *tree, BVHNode *node)
BVHTreeOverlap * BLI_bvhtree_overlap(const BVHTree *tree1, const BVHTree *tree2, uint *r_overlap_num, BVHTree_OverlapCallback callback, void *userdata)
static void tree_overlap_traverse_self_cb(BVHOverlapData_Thread *data_thread, const BVHNode *node)
bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
static void tree_overlap_traverse(BVHOverlapData_Thread *data_thread, const BVHNode *node1, const BVHNode *node2)
void BLI_bvhtree_ray_cast_all(const BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist, BVHTree_RayCastCallback callback, void *userdata)
static void node_minmax_init(const BVHTree *tree, BVHNode *node)
int BLI_bvhtree_get_len(const BVHTree *tree)
static const float bvhtree_kdop_axes_length[13]
static void tree_overlap_invoke_traverse(BVHOverlapData_Thread *data, const BVHNode *node1, const BVHNode *node2)
int BLI_bvhtree_overlap_thread_num(const BVHTree *tree)
static void partition_nth_element(BVHNode **a, int begin, int end, const int n, const int axis)
int BLI_bvhtree_ray_cast_ex(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata, int flag)
static void split_leafs(BVHNode **leafs_array, const int nth[], const int partitions, const int split_axis)
BVHTreeOverlap * BLI_bvhtree_overlap_self(const BVHTree *tree, uint *r_overlap_num, BVHTree_OverlapCallback callback, void *userdata)
BVHTreeOverlap * BLI_bvhtree_overlap_ex(const BVHTree *tree1, const BVHTree *tree2, uint *r_overlap_num, BVHTree_OverlapCallback callback, void *userdata, const uint max_interactions, const int flag)
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
static BVHNode * bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis)
float BLI_bvhtree_get_epsilon(const BVHTree *tree)
static void bvhtree_nearest_projected_dfs_recursive(BVHNearestProjectedData *__restrict data, const BVHNode *node)
static float calc_nearest_point_squared(const float proj[3], BVHNode *node, float nearest[3])
static int implicit_needed_branches(int tree_type, int leafs)
static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node)
int BLI_bvhtree_ray_cast(const BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
int BLI_bvhtree_find_nearest_ex(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata, int flag)
int BLI_bvhtree_range_query(const BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata)
static void create_kdop_hull(const BVHTree *tree, BVHNode *node, const float *co, int numpoints, int moving)
static void bvhtree_overlap_task_cb(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict)
static void bvhtree_intersect_plane_dfs_recursive(BVHIntersectPlaneData *__restrict data, const BVHNode *node)
static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, const int child_index)
static void tree_overlap_invoke_traverse_self(BVHOverlapData_Thread *data_thread, const BVHNode *node)
#define BVH_RAYCAST_DIST_MAX
#define BVH_RAYCAST_DEFAULT
const float bvhtree_kdop_axes[13][3]
bool(*)(void *userdata, int index_a, int index_b, int thread) BVHTree_OverlapCallback
void(*)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit) BVHTree_RayCastCallback
@ BVH_OVERLAP_USE_THREADING
@ BVH_OVERLAP_RETURN_PAIRS
void(*)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest) BVHTree_NearestPointCallback
void(*)(void *userdata, int index, const float co[3], float dist_sq) BVHTree_RangeQuery
void(*)(void *userdata, int index, const DistProjectedAABBPrecalc *precalc, const float(*clip_plane)[4], int clip_plane_len, BVHTreeNearest *nearest) BVHTree_NearestProjectedCallback
@ BVH_NEAREST_OPTIMAL_ORDER
MINLINE float max_fff(float a, float b, float c)
MINLINE float max_ff(float a, float b)
MINLINE int min_ii(int a, int b)
MINLINE int max_ii(int a, int b)
#define BLI_ASSERT_UNIT_V3(v)
void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc, const float ray_direction[3])
float dist_squared_to_projected_aabb(struct DistProjectedAABBPrecalc *data, const float bbmin[3], const float bbmax[3], bool r_axis_closest[3])
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
#define ISECT_AABB_PLANE_CROSS_ANY
#define ISECT_AABB_PLANE_BEHIND_ANY
void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *precalc, const float projmat[4][4], const float winsize[2], const float mval[2])
void aabb_get_near_far_from_plane(const float plane_no[3], const float bbmin[3], const float bbmax[3], float bb_near[3], float bb_afar[3])
int isect_aabb_planes_v3(const float(*planes)[4], int totplane, const float bbmin[3], const float bbmax[3])
void planes_from_projmat(const float mat[4][4], float left[4], float right[4], float bottom[4], float top[4], float near[4], float far[4])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
MINLINE float normalize_v3(float n[3])
void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n) ATTR_NONNULL()
size_t BLI_stack_count(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void BLI_stack_free(BLI_Stack *stack) ATTR_NONNULL()
void * BLI_stack_push_r(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
#define BLI_stack_new(esize, descr)
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Read Guarded memory(de)allocation.
BMesh const char void * data
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
size_t(* MEM_allocN_len)(const void *vmemh)
void MEM_freeN(void *vmemh)
VecBase< float, 3 > float3
int branches_on_level[32]
const BVHBuildHelper * data
BVHTree_NearestPointCallback callback
DistProjectedAABBPrecalc precalc
BVHTree_NearestProjectedCallback callback
BVHNode(const BoundBox &bounds)
BVHOverlapData_Shared * shared
BVHTree_RayCastCallback callback
BVHTree_RangeQuery callback