47#define MAX_TREETYPE 32
53# define KDOPBVH_THREAD_LEAF_THRESHOLD 0
55# define KDOPBVH_THREAD_LEAF_THRESHOLD 1024
92 (
sizeof(
void *) == 4 &&
sizeof(
BVHTree) <= 32),
98 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) {
311 a, begin, end,
bvh_medianof3(a, begin, (begin + end) / 2, end - 1, axis), axis);
327 node->skip[0] =
left;
328 node->skip[1] = right;
330 for (i = 0; i < node->node_num; i++) {
331 if (i + 1 < node->node_num) {
332 build_skip_links(
tree, node->children[i], left, node->children[i + 1]);
335 build_skip_links(
tree, node->children[i], left, right);
338 left = node->children[i];
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 if (newminmax < bv[2 * axis_iter]) {
364 bv[2 * axis_iter] = newminmax;
366 if (newminmax > bv[(2 * axis_iter) + 1]) {
367 bv[(2 * axis_iter) + 1] = newminmax;
378 float newmin, newmax;
379 float *__restrict bv = node->bv;
385 for (j = start; j < end; j++) {
386 const float *__restrict node_bv =
tree->nodes[j]->bv;
389 for (axis_iter =
tree->start_axis; axis_iter <
tree->stop_axis; axis_iter++) {
390 newmin = node_bv[(2 * axis_iter)];
391 if (newmin < bv[(2 * axis_iter)]) {
392 bv[(2 * axis_iter)] = newmin;
395 newmax = node_bv[(2 * axis_iter) + 1];
396 if (newmax > bv[(2 * axis_iter) + 1]) {
397 bv[(2 * axis_iter) + 1] = newmax;
409 float middle_point[3];
411 middle_point[0] = (bv[1]) - (bv[0]);
412 middle_point[1] = (bv[3]) - (bv[2]);
413 middle_point[2] = (bv[5]) - (bv[4]);
414 if (middle_point[0] > middle_point[1]) {
415 if (middle_point[0] > middle_point[2]) {
420 if (middle_point[1] > middle_point[2]) {
437 for (i = 0; i <
tree->tree_type; i++) {
438 if (node->children[i]) {
439 for (axis_iter =
tree->start_axis; axis_iter <
tree->stop_axis; axis_iter++) {
441 if (node->children[i]->bv[(2 * axis_iter)] < node->bv[(2 * axis_iter)]) {
442 node->bv[(2 * axis_iter)] = node->children[i]->bv[(2 * axis_iter)];
446 if (node->children[i]->bv[(2 * axis_iter) + 1] > node->bv[(2 * axis_iter) + 1]) {
447 node->bv[(2 * axis_iter) + 1] = node->children[i]->bv[(2 * axis_iter) + 1];
468 for (i = 0; i < depth; i++) {
471 printf(
" - %d (%ld): ", node->index, (
long int)(node -
tree->nodearray));
475 printf(
"%.3f ", node->bv[axis_iter]);
479 for (i = 0; i <
tree->tree_type; i++) {
480 if (node->children[i]) {
481 bvhtree_print_tree(
tree, node->children[i], depth + 1);
488 printf(
"BVHTree Info: tree_type = %d, axis = %d, epsilon = %f\n",
492 printf(
"nodes = %d, branches = %d, leafs = %d\n",
497 "Memory per node = %ubytes\n",
501 printf(
"Total memory = %ubytes\n",
505 bvhtree_print_tree(
tree,
tree->nodes[
tree->leaf_num], 0);
512#ifdef USE_VERIFY_TREE
519 for (i = 0; i <
tree->leaf_num; i++) {
520 if (
tree->nodes[i]->parent ==
NULL) {
521 printf(
"Leaf has no parent: %d\n", i);
524 for (j = 0; j <
tree->tree_type; j++) {
525 if (
tree->nodes[i]->parent->children[j] ==
tree->nodes[i]) {
530 printf(
"Parent child relationship doesn't match: %d\n", i);
537 for (i = 0; i <
tree->leaf_num; i++) {
538 if (
tree->nodearray[i].parent ==
NULL) {
539 printf(
"Leaf has no parent: %d\n", i);
542 for (j = 0; j <
tree->tree_type; j++) {
543 if (
tree->nodearray[i].parent->children[j] == &
tree->nodearray[i]) {
548 printf(
"Parent child relationship doesn't match: %d\n", i);
554 printf(
"branches: %d, leafs: %d, total: %d\n",
585 data->tree_type =
tree->tree_type;
588 for (data->leafs_per_child[0] = 1; data->leafs_per_child[0] < data->leafs_num;
589 data->leafs_per_child[0] *= data->tree_type)
594 data->branches_on_level[0] = 1;
596 for (depth = 1; (depth < 32) && data->leafs_per_child[depth - 1]; depth++) {
597 data->branches_on_level[depth] = data->branches_on_level[depth - 1] * data->tree_type;
598 data->leafs_per_child[depth] = data->leafs_per_child[depth - 1] / data->tree_type;
601 remain = data->leafs_num - data->leafs_per_child[1];
602 nnodes = (remain + data->tree_type - 2) / (data->tree_type - 1);
603 data->remain_leafs = remain + nnodes;
611 int min_leaf_index = child_index * data->leafs_per_child[depth - 1];
612 if (min_leaf_index <= data->remain_leafs) {
613 return min_leaf_index;
615 if (data->leafs_per_child[depth]) {
616 return data->leafs_num -
617 (data->branches_on_level[depth - 1] - child_index) * data->leafs_per_child[depth];
619 return data->remain_leafs;
654 return max_ii(1, (leafs + tree_type - 3) / (tree_type - 1));
671 const int partitions,
672 const int split_axis)
675 for (i = 0; i < partitions - 1; i++) {
676 if (nth[i] >= nth[partitions]) {
706 const int parent_level_index = j - data->
i;
707 BVHNode *parent = &data->branches_array[j];
716 refit_kdop_hull(data->tree, parent, parent_leafs_begin, parent_leafs_end);
726 nth_positions[0] = parent_leafs_begin;
727 nth_positions[data->tree_type] = parent_leafs_end;
728 for (k = 1; 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;
735 split_leafs(data->leafs_array, nth_positions, data->tree_type, split_axis);
740 for (k = 0; k < data->tree_type; k++) {
741 const int child_index = j * data->tree_type + data->tree_offset + k;
743 const int child_level_index = child_index - data->first_of_next_level;
746 data->data, data->depth + 1, child_level_index);
748 data->data, data->depth + 1, child_level_index + 1);
750 if (child_leafs_end - child_leafs_begin > 1) {
751 parent->
children[k] = &data->branches_array[child_index];
754 else if (child_leafs_end - child_leafs_begin == 1) {
755 parent->
children[k] = data->leafs_array[child_leafs_begin];
790 const int tree_type =
tree->tree_type;
792 const int tree_offset = 2 -
tree->tree_type;
801 BVHNode *root = &branches_array[1];
806 if (leafs_num == 1) {
820 .branches_array = branches_array,
821 .leafs_array = leafs_array,
822 .tree_type = tree_type,
823 .tree_offset = tree_offset,
825 .first_of_next_level = 0,
831 for (i = 1, depth = 1; i <= branches_num; i = i * tree_type + tree_offset, depth++) {
832 const int first_of_next_level = i * tree_type + tree_offset;
834 const int i_stop =
min_ii(first_of_next_level, branches_num + 1);
839 cb_data.
depth = depth;
850 for (
int i_task = i; i_task < i_stop; i_task++) {
876 epsilon =
max_ff(FLT_EPSILON, epsilon);
879 tree->epsilon = epsilon;
880 tree->tree_type = tree_type;
884 tree->start_axis = 0;
885 tree->stop_axis = 13;
887 else if (axis == 18) {
888 tree->start_axis = 7;
889 tree->stop_axis = 13;
891 else if (axis == 14) {
892 tree->start_axis = 0;
895 else if (axis == 8) {
896 tree->start_axis = 0;
899 else if (axis == 6) {
900 tree->start_axis = 0;
914 tree->nodebv =
MEM_callocN(
sizeof(
float) * (
size_t)(axis * numnodes),
"BVHNodeBV");
923 for (i = 0; i < numnodes; i++) {
924 tree->nodearray[i].bv = &
tree->nodebv[i * axis];
925 tree->nodearray[i].children = &
tree->nodechild[i * tree_type];
961 for (
int i = 0; i <
tree->branch_num; i++) {
969#ifdef USE_VERIFY_TREE
970 bvhtree_verify(
tree);
981 for (axis_iter =
tree->start_axis; axis_iter <
tree->stop_axis; axis_iter++) {
983 node->bv[(2 * axis_iter)] -= dist_corrected;
984 node->bv[(2 * axis_iter) + 1] += dist_corrected;
1000 node->index = index;
1007 BVHTree *
tree,
int index,
const float co[3],
const float co_moving[3],
int numpoints)
1012 if (index >
tree->leaf_num) {
1016 node =
tree->nodearray + index;
1039 for (; index >= root; index--) {
1045 return tree->leaf_num;
1050 return tree->tree_type;
1055 return tree->epsilon;
1062 const float bb_min[3] = {root->
bv[0], root->
bv[2], root->
bv[4]};
1063 const float bb_max[3] = {root->
bv[1], root->
bv[3], root->
bv[5]};
1088 const float *bv1 = node1->
bv + (start_axis << 1);
1089 const float *bv2 = node2->
bv + (start_axis << 1);
1090 const float *bv1_end = node1->
bv + (stop_axis << 1);
1093 for (; bv1 != bv1_end; bv1 += 2, bv2 += 2) {
1094 if ((bv1[0] > bv2[1]) || (bv2[0] > bv1[1])) {
1126 for (j = 0; j < data->tree2->tree_type; j++) {
1134 for (j = 0; j < data->tree1->tree_type; j++) {
1165 if (data->callback(data->userdata, node1->
index, node2->
index, data_thread->
thread)) {
1173 for (j = 0; j < data->tree2->tree_type; j++) {
1181 for (j = 0; j < data->tree1->tree_type; j++) {
1212 if (!data->callback ||
1213 data->callback(data->userdata, node1->
index, node2->
index, data_thread->
thread))
1225 for (j = 0; j < node2->
node_num; j++) {
1234 for (j = 0; j < node1->
node_num; j++) {
1249 if (data->max_interactions) {
1252 else if (data->shared->callback) {
1263 for (
int i = 0; i < node->node_num; i++) {
1268 for (
int j = i + 1; j < node->node_num; j++) {
1277 for (
int i = 0; i < node->node_num; i++) {
1282 for (
int j = i + 1; j < node->node_num; j++) {
1292 if (data_thread->
shared->callback) {
1312 const BVHNode *root1 = data_shared->tree1->nodes[data_shared->tree1->leaf_num];
1314 if (data_shared->use_self) {
1318 for (
int k = j + 1; k < root1->
node_num; k++) {
1323 const BVHNode *root2 = data_shared->tree2->nodes[data_shared->tree2->leaf_num];
1332 uint *r_overlap_num,
1336 const uint max_interactions,
1345 BLI_assert(overlap_pairs || max_interactions);
1347 BLI_assert(!use_self || (tree1 == tree2 && !max_interactions));
1350 const int thread_num = use_threading ? root_node_len : 1;
1356 axis_t start_axis, stop_axis;
1360 (tree1->
axis == 18 || tree2->
axis == 18)))
1366 if (
UNLIKELY(use_self && tree1 != tree2)) {
1381 data_shared.tree1 = tree1;
1382 data_shared.tree2 = tree2;
1384 data_shared.stop_axis = stop_axis;
1385 data_shared.use_self = use_self;
1389 data_shared.userdata = userdata;
1391 for (j = 0; j < thread_num; j++) {
1393 data[j].shared = &data_shared;
1395 data[j].max_interactions = use_self ? 0 : max_interactions;
1401 if (use_threading) {
1404 settings.min_iter_per_thread = 1;
1407 else if (use_self) {
1414 if (overlap_pairs) {
1415 for (j = 0; j < thread_num; j++) {
1421 for (j = 0; j < thread_num; j++) {
1427 *r_overlap_num = (
uint)total;
1436 uint *r_overlap_num,
1452 uint *r_overlap_num,
1476 const float bb_min[3] = {bv[0], bv[2], bv[4]};
1477 const float bb_max[3] = {bv[1], bv[3], bv[5]};
1478 float bb_near[3], bb_far[3];
1493 if (!node->node_num) {
1498 for (
int j = 0; j < data->tree->tree_type; j++) {
1499 if (node->children[j]) {
1512 if (
tree->leaf_num) {
1528 *r_intersect_num = (
uint)total;
1543 const float *bv = node->bv;
1546 for (i = 0; i != 3; i++, bv += 2) {
1547 float val = proj[i];
1563 if (node->node_num == 0) {
1564 if (data->callback) {
1565 data->callback(data->userdata, node->index, data->co, &data->nearest);
1568 data->nearest.index = node->index;
1577 if (data->proj[node->main_axis] <= node->children[0]->bv[node->main_axis * 2 + 1]) {
1579 for (i = 0; i != node->node_num; i++) {
1581 data->nearest.dist_sq)
1589 for (i = node->node_num - 1; i >= 0; i--) {
1591 data->nearest.dist_sq)
1603 float nearest[3], dist_sq;
1605 if (dist_sq >= data->nearest.dist_sq) {
1614 if (node->node_num == 0) {
1615 if (data->callback) {
1616 data->callback(data->userdata, node->index, data->co, &data->nearest);
1619 data->nearest.index = node->index;
1626 for (
int i = 0; i != node->node_num; i++) {
1629 if (dist_sq < data->nearest.dist_sq) {
1641 if (dist_sq < data->nearest.dist_sq) {
1674 data.userdata = userdata;
1676 for (axis_iter = data.tree->start_axis; axis_iter != data.tree->stop_axis; axis_iter++) {
1681 memcpy(&data.nearest, nearest,
sizeof(*nearest));
1684 data.nearest.index = -1;
1685 data.nearest.dist_sq =
FLT_MAX;
1700 memcpy(nearest, &data.nearest,
sizeof(*nearest));
1703 return data.nearest.index;
1725 if (co[0] > bv[0].
min && co[0] < bv[0].max && co[1] > bv[1].
min && co[1] < bv[1].max &&
1726 co[2] > bv[2].
min && co[2] < bv[2].max)
1736 if (node->node_num == 0) {
1738 if (data->callback) {
1739 const float dist_sq = data->nearest.dist_sq;
1740 data->callback(data->userdata, node->index, data->co, &data->nearest);
1741 return (data->nearest.dist_sq < dist_sq);
1743 data->nearest.index = node->index;
1751 if (data->proj[node->main_axis] <= node->children[0]->bv[node->main_axis * 2 + 1]) {
1752 for (i = 0; i != node->node_num; i++) {
1761 for (i = node->node_num; i--;) {
1775 const float dist_sq,
1787 data.userdata = userdata;
1788 data.nearest.index = -1;
1789 data.nearest.dist_sq = dist_sq;
1796 return data.nearest.index;
1813 float low = 0, upper = data->hit.dist;
1815 for (i = 0; i != 3; i++, bv += 2) {
1816 if (data->ray_dot_axis[i] == 0.0f) {
1818 if (data->ray.origin[i] < bv[0] - data->ray.radius ||
1819 data->ray.origin[i] > bv[1] + data->ray.radius)
1825 float ll = (bv[0] - data->ray.radius - data->ray.origin[i]) / data->ray_dot_axis[i];
1826 float lu = (bv[1] + data->ray.radius - data->ray.origin[i]) / data->ray_dot_axis[i];
1828 if (data->ray_dot_axis[i] > 0.0f) {
1861 const float *bv = node->bv;
1863 float t1x = (bv[data->index[0]] - data->ray.origin[0]) * data->idot_axis[0];
1864 float t2x = (bv[data->index[1]] - data->ray.origin[0]) * data->idot_axis[0];
1865 float t1y = (bv[data->index[2]] - data->ray.origin[1]) * data->idot_axis[1];
1866 float t2y = (bv[data->index[3]] - data->ray.origin[1]) * data->idot_axis[1];
1867 float t1z = (bv[data->index[4]] - data->ray.origin[2]) * data->idot_axis[2];
1868 float t2z = (bv[data->index[5]] - data->ray.origin[2]) * data->idot_axis[2];
1870 if ((t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) ||
1871 (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) ||
1872 (t1x > data->hit.dist || t1y > data->hit.dist || t1z > data->hit.dist))
1876 return max_fff(t1x, t1y, t1z);
1888 if (dist >= data->hit.dist) {
1892 if (node->node_num == 0) {
1893 if (data->callback) {
1894 data->callback(data->userdata, node->index, &data->ray, &data->hit);
1897 data->hit.index = node->index;
1898 data->hit.dist = dist;
1899 madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist);
1904 if (data->ray_dot_axis[node->main_axis] > 0.0f) {
1905 for (i = 0; i != node->node_num; i++) {
1910 for (i = node->node_num - 1; i >= 0; i--) {
1929 if (dist >= data->hit.dist) {
1933 if (node->node_num == 0) {
1935 dist = data->hit.dist;
1936 data->callback(data->userdata, node->index, &data->ray, &data->hit);
1937 data->hit.index = -1;
1938 data->hit.dist = dist;
1942 if (data->ray_dot_axis[node->main_axis] > 0.0f) {
1943 for (i = 0; i != node->node_num; i++) {
1948 for (i = node->node_num - 1; i >= 0; i--) {
1959 for (i = 0; i < 3; i++) {
1962 if (
fabsf(data->ray_dot_axis[i]) < FLT_EPSILON) {
1963 data->ray_dot_axis[i] = 0.0f;
1968 data->idot_axis[i] = 1.0f / data->ray_dot_axis[i];
1971 data->index[2 * i] = data->idot_axis[i] < 0.0f ? 1 : 0;
1972 data->index[2 * i + 1] = 1 - data->index[2 * i];
1973 data->index[2 * i] += 2 * i;
1974 data->index[2 * i + 1] += 2 * i;
1977#ifdef USE_KDOPBVH_WATERTIGHT
1980 data->ray.isect_precalc = &data->isect_precalc;
1983 data->ray.isect_precalc =
NULL;
2007 data.userdata = userdata;
2011 data.ray.radius = radius;
2016 memcpy(&data.hit, hit,
sizeof(*hit));
2019 data.hit.index = -1;
2029 memcpy(hit, &data.hit,
sizeof(*hit));
2032 return data.hit.index;
2048 const float light_start[3],
2049 const float light_end[3],
2058 sub_v3_v3v3(data.ray.direction, light_end, light_start);
2060 data.ray.radius = 0.0;
2065 copy_v3_v3(data.ray_dot_axis, data.ray.direction);
2092 data.userdata = userdata;
2096 data.ray.radius = radius;
2100 data.hit.index = -1;
2101 data.hit.dist = hit_dist;
2144 if (node->node_num == 0) {
2149 co[0] = node->bv[0];
2150 co[1] = node->bv[2];
2151 co[2] = node->bv[4];
2156 for (i = 0; i != node->node_num; i++) {
2159 if (dist_sq < data->radius_sq) {
2161 if (node->children[i]->node_num == 0) {
2163 data->callback(data->userdata, node->children[i]->index, data->center, dist_sq);
2184 data.radius_sq = radius * radius;
2188 data.userdata = userdata;
2193 if (dist_sq < data.radius_sq) {
2197 data.callback(data.userdata, root->
index, co, dist_sq);
2217 if (node->node_num == 0) {
2218 if (data->callback) {
2219 data->callback(data->userdata, node->index, &data->precalc,
NULL, 0, &data->nearest);
2222 data->nearest.index = node->index;
2225 (
float[3]){node->bv[0], node->bv[2], node->bv[4]},
2226 (
float[3]){node->bv[1], node->bv[3], node->bv[5]},
2227 data->closest_axis);
2232 if (data->closest_axis[node->main_axis]) {
2233 for (
int i = 0; i != node->node_num; i++) {
2234 const float *bv = node->children[i]->bv;
2237 (
float[3]){bv[0], bv[2], bv[4]},
2238 (
float[3]){bv[1], bv[3], bv[5]},
2239 data->closest_axis) <= data->nearest.dist_sq)
2246 for (
int i = node->node_num; i--;) {
2247 const float *bv = node->children[i]->bv;
2250 (
float[3]){bv[0], bv[2], bv[4]},
2251 (
float[3]){bv[1], bv[3], bv[5]},
2252 data->closest_axis) <= data->nearest.dist_sq)
2264 if (node->node_num == 0) {
2265 if (data->callback) {
2266 data->callback(data->userdata,
2270 data->clip_plane_len,
2274 data->nearest.index = node->index;
2277 (
float[3]){node->bv[0], node->bv[2], node->bv[4]},
2278 (
float[3]){node->bv[1], node->bv[3], node->bv[5]},
2279 data->closest_axis);
2284 if (data->closest_axis[node->main_axis]) {
2285 for (
int i = 0; i != node->node_num; i++) {
2286 const float *bv = node->children[i]->bv;
2287 const float bb_min[3] = {bv[0], bv[2], bv[4]};
2288 const float bb_max[3] = {bv[1], bv[3], bv[5]};
2291 data->clip_plane, data->clip_plane_len, bb_min, bb_max);
2295 data->nearest.dist_sq)
2308 for (
int i = node->node_num; i--;) {
2309 const float *bv = node->children[i]->bv;
2310 const float bb_min[3] = {bv[0], bv[2], bv[4]};
2311 const float bb_max[3] = {bv[1], bv[3], bv[5]};
2314 data->clip_plane, data->clip_plane_len, bb_min, bb_max);
2318 data->nearest.dist_sq)
2334 float projmat[4][4],
2337 float (*clip_plane)[4],
2346 sizeof(*data) + (
sizeof(*clip_plane) * (size_t)
max_ii(1, clip_plane_len)));
2351 data->userdata = userdata;
2354 data->clip_plane_len = clip_plane_len;
2355 for (
int i = 0; i < clip_plane_len; i++) {
2356 copy_v4_v4(data->clip_plane[i], clip_plane[i]);
2360 data->clip_plane_len = 1;
2365 memcpy(&data->nearest, nearest,
sizeof(*nearest));
2368 data->nearest.index = -1;
2369 data->nearest.dist_sq =
FLT_MAX;
2372 const float bb_min[3] = {root->
bv[0], root->
bv[2], root->
bv[4]};
2373 const float bb_max[3] = {root->
bv[1], root->
bv[3], root->
bv[5]};
2376 data->clip_plane, data->clip_plane_len, bb_min, bb_max);
2378 if (isect_type != 0 &&
2380 data->nearest.dist_sq)
2382 if (isect_type == 1) {
2392 memcpy(nearest, &data->nearest,
sizeof(*nearest));
2395 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])
struct BVHNearestProjectedData BVHNearestProjectedData
struct BVHIntersectPlaneData BVHIntersectPlaneData
struct RangeQueryData RangeQueryData
struct BVHRayCastData BVHRayCastData
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)
const float bvhtree_kdop_axes[13][3]
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])
struct BVHOverlapData_Thread BVHOverlapData_Thread
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)
struct BVHNearestData BVHNearestData
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 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)
struct BVHDivNodesData BVHDivNodesData
static void non_recursive_bvh_div_nodes_task_cb(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict UNUSED(tls))
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)
static void bvhtree_overlap_task_cb(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict UNUSED(tls))
struct BVHBuildHelper BVHBuildHelper
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_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)
@ BVH_OVERLAP_USE_THREADING
@ BVH_OVERLAP_RETURN_PAIRS
@ BVH_NEAREST_OPTIMAL_ORDER
#define BVH_RAYCAST_DIST_MAX
#define BVH_RAYCAST_DEFAULT
void(* BVHTree_RayCastCallback)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
void(* BVHTree_NearestPointCallback)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
bool(* BVHTree_OverlapCallback)(void *userdata, int index_a, int index_b, int thread)
void(* BVHTree_RangeQuery)(void *userdata, int index, const float co[3], float dist_sq)
void(* BVHTree_NearestProjectedCallback)(void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, const float(*clip_plane)[4], int clip_plane_len, BVHTreeNearest *nearest)
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.
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)
local_group_size(16, 16) .push_constant(Type b
DEGForeachIDComponentCallback callback
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
size_t(* MEM_allocN_len)(const void *vmemh)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
int branches_on_level[32]
const BVHBuildHelper * data
BVHTree_NearestPointCallback callback
struct DistProjectedAABBPrecalc precalc
BVHTree_NearestProjectedCallback callback
struct BVHNode ** children
BVHOverlapData_Shared * shared
BVHTree_RayCastCallback callback
BVHTree_RangeQuery callback