62 #define MAX_TREETYPE 32
68 # define KDOPBVH_THREAD_LEAF_THRESHOLD 0
70 # define KDOPBVH_THREAD_LEAF_THRESHOLD 1024
107 (
sizeof(
void *) == 4 &&
sizeof(
BVHTree) <= 32),
113 axis_t start_axis, stop_axis;
146 #ifdef USE_KDOPBVH_WATERTIGHT
225 return (
a < b) ?
a : b;
230 return (b <
a) ?
a : b;
246 for (axis_iter =
tree->start_axis; axis_iter !=
tree->stop_axis; axis_iter++) {
247 bv[axis_iter][0] = FLT_MAX;
248 bv[axis_iter][1] = -FLT_MAX;
265 for (i = lo; i < hi; i++) {
268 while ((j != lo) && (
t->bv[axis] < (
a[j - 1])->bv[axis])) {
280 while (
a[i]->bv[axis] <
x->bv[axis]) {
284 while (
x->bv[axis] <
a[j]->bv[axis]) {
298 if ((
a[mid])->bv[axis] < (
a[lo])->bv[axis]) {
299 if ((
a[hi])->bv[axis] < (
a[mid])->bv[axis]) {
302 if ((
a[hi])->bv[axis] < (
a[lo])->bv[axis]) {
308 if ((
a[hi])->bv[axis] < (
a[mid])->bv[axis]) {
309 if ((
a[hi])->bv[axis] < (
a[lo])->bv[axis]) {
323 while (end - begin > 3) {
325 a, begin, end,
bvh_medianof3(
a, begin, (begin + end) / 2, end - 1, axis), axis);
336 #ifdef USE_SKIP_LINKS
344 for (i = 0; i <
node->totnode; i++) {
345 if (i + 1 <
node->totnode) {
364 float *bv =
node->bv;
373 for (k = 0; k < numpoints; k++) {
375 for (axis_iter =
tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
377 if (newminmax < bv[2 * axis_iter]) {
378 bv[2 * axis_iter] = newminmax;
380 if (newminmax > bv[(2 * axis_iter) + 1]) {
381 bv[(2 * axis_iter) + 1] = newminmax;
392 float newmin, newmax;
393 float *__restrict bv =
node->bv;
399 for (j = start; j < end; j++) {
400 float *__restrict node_bv =
tree->nodes[j]->bv;
403 for (axis_iter =
tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
404 newmin = node_bv[(2 * axis_iter)];
405 if ((newmin < bv[(2 * axis_iter)])) {
406 bv[(2 * axis_iter)] = newmin;
409 newmax = node_bv[(2 * axis_iter) + 1];
410 if ((newmax > bv[(2 * axis_iter) + 1])) {
411 bv[(2 * axis_iter) + 1] = newmax;
422 float middle_point[3];
424 middle_point[0] = (bv[1]) - (bv[0]);
425 middle_point[1] = (bv[3]) - (bv[2]);
426 middle_point[2] = (bv[5]) - (bv[4]);
427 if (middle_point[0] > middle_point[1]) {
428 if (middle_point[0] > middle_point[2]) {
433 if (middle_point[1] > middle_point[2]) {
449 for (i = 0; i <
tree->tree_type; i++) {
450 if (
node->children[i]) {
451 for (axis_iter =
tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
453 if (
node->children[i]->bv[(2 * axis_iter)] <
node->bv[(2 * axis_iter)]) {
454 node->bv[(2 * axis_iter)] =
node->children[i]->bv[(2 * axis_iter)];
458 if (
node->children[i]->bv[(2 * axis_iter) + 1] >
node->bv[(2 * axis_iter) + 1]) {
459 node->bv[(2 * axis_iter) + 1] =
node->children[i]->bv[(2 * axis_iter) + 1];
469 #ifdef USE_PRINT_TREE
480 for (i = 0; i < depth; i++) {
483 printf(
" - %d (%ld): ",
node->index, (
long int)(
node -
tree->nodearray));
486 printf(
"%.3f ",
node->bv[axis_iter]);
490 for (i = 0; i <
tree->tree_type; i++) {
491 if (
node->children[i]) {
492 bvhtree_print_tree(
tree,
node->children[i], depth + 1);
499 printf(
"BVHTree Info: tree_type = %d, axis = %d, epsilon = %f\n",
503 printf(
"nodes = %d, branches = %d, leafs = %d\n",
508 "Memory per node = %ubytes\n",
512 printf(
"Total memory = %ubytes\n",
516 bvhtree_print_tree(
tree,
tree->nodes[
tree->totleaf], 0);
520 #ifdef USE_VERIFY_TREE
527 for (i = 0; i <
tree->totleaf; i++) {
528 if (
tree->nodes[i]->parent ==
NULL) {
529 printf(
"Leaf has no parent: %d\n", i);
532 for (j = 0; j <
tree->tree_type; j++) {
533 if (
tree->nodes[i]->parent->children[j] ==
tree->nodes[i]) {
538 printf(
"Parent child relationship doesn't match: %d\n", i);
545 for (i = 0; i <
tree->totleaf; i++) {
546 if (
tree->nodearray[i].parent ==
NULL) {
547 printf(
"Leaf has no parent: %d\n", i);
550 for (j = 0; j <
tree->tree_type; j++) {
551 if (
tree->nodearray[i].parent->children[j] == &
tree->nodearray[i]) {
556 printf(
"Parent child relationship doesn't match: %d\n", i);
562 printf(
"branches: %d, leafs: %d, total: %d\n",
596 for (
data->leafs_per_child[0] = 1;
data->leafs_per_child[0] <
data->totleafs;
597 data->leafs_per_child[0] *=
data->tree_type) {
601 data->branches_on_level[0] = 1;
603 for (depth = 1; (depth < 32) &&
data->leafs_per_child[depth - 1]; depth++) {
604 data->branches_on_level[depth] =
data->branches_on_level[depth - 1] *
data->tree_type;
605 data->leafs_per_child[depth] =
data->leafs_per_child[depth - 1] /
data->tree_type;
608 remain =
data->totleafs -
data->leafs_per_child[1];
609 nnodes = (remain +
data->tree_type - 2) / (
data->tree_type - 1);
610 data->remain_leafs = remain + nnodes;
618 int min_leaf_index = child_index *
data->leafs_per_child[depth - 1];
619 if (min_leaf_index <= data->remain_leafs) {
620 return min_leaf_index;
622 if (
data->leafs_per_child[depth]) {
623 return data->totleafs -
624 (
data->branches_on_level[depth - 1] - child_index) *
data->leafs_per_child[depth];
626 return data->remain_leafs;
661 return max_ii(1, (leafs + tree_type - 3) / (tree_type - 1));
678 const int partitions,
679 const int split_axis)
682 for (i = 0; i < partitions - 1; i++) {
683 if (nth[i] >= nth[partitions]) {
713 const int parent_level_index = j -
data->i;
733 nth_positions[0] = parent_leafs_begin;
734 nth_positions[
data->tree_type] = parent_leafs_end;
735 for (k = 1; k <
data->tree_type; k++) {
736 const int child_index = j *
data->tree_type +
data->tree_offset + k;
738 const int child_level_index = child_index -
data->first_of_next_level;
747 for (k = 0; k <
data->tree_type; k++) {
748 const int child_index = j *
data->tree_type +
data->tree_offset + k;
750 const int child_level_index = child_index -
data->first_of_next_level;
753 data->data,
data->depth + 1, child_level_index);
755 data->data,
data->depth + 1, child_level_index + 1);
757 if (child_leafs_end - child_leafs_begin > 1) {
758 parent->
children[k] = &
data->branches_array[child_index];
761 else if (child_leafs_end - child_leafs_begin == 1) {
762 parent->
children[k] =
data->leafs_array[child_leafs_begin];
797 const int tree_type =
tree->tree_type;
799 const int tree_offset = 2 -
tree->tree_type;
808 BVHNode *root = &branches_array[1];
813 if (num_leafs == 1) {
827 .branches_array = branches_array,
828 .leafs_array = leafs_array,
829 .tree_type = tree_type,
830 .tree_offset = tree_offset,
832 .first_of_next_level = 0,
838 for (i = 1, depth = 1; i <= num_branches; i = i * tree_type + tree_offset, depth++) {
839 const int first_of_next_level = i * tree_type + tree_offset;
841 const int i_stop =
min_ii(first_of_next_level, num_branches + 1);
846 cb_data.
depth = depth;
857 for (
int i_task = i; i_task < i_stop; i_task++) {
890 tree->tree_type = tree_type;
894 tree->start_axis = 0;
895 tree->stop_axis = 13;
897 else if (axis == 18) {
898 tree->start_axis = 7;
899 tree->stop_axis = 13;
901 else if (axis == 14) {
902 tree->start_axis = 0;
905 else if (axis == 8) {
906 tree->start_axis = 0;
909 else if (axis == 6) {
910 tree->start_axis = 0;
924 tree->nodebv =
MEM_callocN(
sizeof(
float) * (
size_t)(axis * numnodes),
"BVHNodeBV");
933 for (i = 0; i < numnodes; i++) {
934 tree->nodearray[i].bv = &
tree->nodebv[i * axis];
935 tree->nodearray[i].children = &
tree->nodechild[i * tree_type];
971 for (
int i = 0; i <
tree->totbranch; i++) {
975 #ifdef USE_SKIP_LINKS
979 #ifdef USE_VERIFY_TREE
980 bvhtree_verify(
tree);
983 #ifdef USE_PRINT_TREE
991 for (axis_iter =
tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
993 node->bv[(2 * axis_iter)] -= dist_corrected;
994 node->bv[(2 * axis_iter) + 1] += dist_corrected;
1010 node->index = index;
1018 BVHTree *
tree,
int index,
const float co[3],
const float co_moving[3],
int numpoints)
1023 if (index >
tree->totleaf) {
1053 for (; index >= root; index--) {
1063 return tree->totleaf;
1071 return tree->tree_type;
1076 return tree->epsilon;
1086 const float bb_min[3] = {root->
bv[0], root->
bv[2], root->
bv[4]};
1087 const float bb_max[3] = {root->
bv[1], root->
bv[3], root->
bv[5]};
1112 const float *bv1 = node1->
bv + (start_axis << 1);
1113 const float *bv2 = node2->
bv + (start_axis << 1);
1114 const float *bv1_end = node1->
bv + (stop_axis << 1);
1117 for (; bv1 != bv1_end; bv1 += 2, bv2 += 2) {
1118 if ((bv1[0] > bv2[1]) || (bv2[0] > bv1[1])) {
1150 for (j = 0; j <
data->tree2->tree_type; j++) {
1158 for (j = 0; j <
data->tree1->tree_type; j++) {
1197 for (j = 0; j <
data->tree2->tree_type; j++) {
1205 for (j = 0; j <
data->tree1->tree_type; j++) {
1236 if (!
data->callback ||
1248 for (j = 0; j < node2->
totnode; j++) {
1257 for (j = 0; j < node1->
totnode; j++) {
1284 if (
data->max_interactions) {
1286 data_shared->tree1->nodes[data_shared->tree1->totleaf]->children[j],
1287 data_shared->tree2->nodes[data_shared->tree2->totleaf]);
1289 else if (data_shared->callback) {
1291 data_shared->tree1->nodes[data_shared->tree1->totleaf]->children[j],
1292 data_shared->tree2->nodes[data_shared->tree2->totleaf]);
1296 data_shared->tree1->nodes[data_shared->tree1->totleaf]->children[j],
1297 data_shared->tree2->nodes[data_shared->tree2->totleaf]);
1304 uint *r_overlap_tot,
1308 const uint max_interactions,
1316 BLI_assert(overlap_pairs || max_interactions);
1319 const int thread_num = use_threading ? root_node_len : 1;
1325 axis_t start_axis, stop_axis;
1329 (tree1->
axis == 18 || tree2->
axis == 18))) {
1345 data_shared.tree1 = tree1;
1346 data_shared.tree2 = tree2;
1348 data_shared.stop_axis = stop_axis;
1352 data_shared.userdata = userdata;
1354 for (j = 0; j < thread_num; j++) {
1356 data[j].shared = &data_shared;
1358 data[j].max_interactions = max_interactions;
1364 if (use_threading) {
1371 if (max_interactions) {
1382 if (overlap_pairs) {
1383 for (j = 0; j < thread_num; j++) {
1389 for (j = 0; j < thread_num; j++) {
1395 *r_overlap_tot = (
uint)total;
1404 uint *r_overlap_tot,
1427 const float bb_min[3] = {bv[0], bv[2], bv[4]};
1428 const float bb_max[3] = {bv[1], bv[3], bv[5]};
1429 float bb_near[3], bb_far[3];
1444 if (!
node->totnode) {
1449 for (
int j = 0; j <
data->tree->tree_type; j++) {
1450 if (
node->children[j]) {
1463 if (
tree->totleaf) {
1479 *r_intersect_tot = (
uint)total;
1494 const float *bv =
node->bv;
1497 for (i = 0; i != 3; i++, bv += 2) {
1498 float val = proj[i];
1514 if (
node->totnode == 0) {
1515 if (
data->callback) {
1528 if (
data->proj[
node->main_axis] <=
node->children[0]->bv[
node->main_axis * 2 + 1]) {
1530 for (i = 0; i !=
node->totnode; i++) {
1532 data->nearest.dist_sq) {
1539 for (i =
node->totnode - 1; i >= 0; i--) {
1541 data->nearest.dist_sq) {
1552 float nearest[3], dist_sq;
1554 if (dist_sq >=
data->nearest.dist_sq) {
1563 if (
node->totnode == 0) {
1564 if (
data->callback) {
1575 for (
int i = 0; i !=
node->totnode; i++) {
1578 if (dist_sq < data->nearest.dist_sq) {
1590 if (dist_sq < data->nearest.dist_sq) {
1622 data.userdata = userdata;
1624 for (axis_iter =
data.tree->start_axis; axis_iter !=
data.tree->stop_axis; axis_iter++) {
1629 memcpy(&
data.nearest, nearest,
sizeof(*nearest));
1632 data.nearest.index = -1;
1633 data.nearest.dist_sq = FLT_MAX;
1648 memcpy(nearest, &
data.nearest,
sizeof(*nearest));
1651 return data.nearest.index;
1673 if (co[0] > bv[0].
min && co[0] < bv[0].
max && co[1] > bv[1].
min && co[1] < bv[1].
max &&
1674 co[2] > bv[2].
min && co[2] < bv[2].
max) {
1683 if (
node->totnode == 0) {
1685 if (
data->callback) {
1686 const float dist_sq =
data->nearest.dist_sq;
1688 return (
data->nearest.dist_sq < dist_sq);
1698 if (
data->proj[
node->main_axis] <=
node->children[0]->bv[
node->main_axis * 2 + 1]) {
1699 for (i = 0; i !=
node->totnode; i++) {
1708 for (i =
node->totnode; i--;) {
1726 const float dist_sq,
1738 data.userdata = userdata;
1739 data.nearest.index = -1;
1740 data.nearest.dist_sq = dist_sq;
1747 return data.nearest.index;
1764 float low = 0, upper =
data->hit.dist;
1766 for (i = 0; i != 3; i++, bv += 2) {
1767 if (
data->ray_dot_axis[i] == 0.0f) {
1769 if (
data->ray.origin[i] < bv[0] -
data->ray.radius ||
1770 data->ray.origin[i] > bv[1] +
data->ray.radius) {
1775 float ll = (bv[0] -
data->ray.radius -
data->ray.origin[i]) /
data->ray_dot_axis[i];
1776 float lu = (bv[1] +
data->ray.radius -
data->ray.origin[i]) /
data->ray_dot_axis[i];
1778 if (
data->ray_dot_axis[i] > 0.0f) {
1811 const float *bv =
node->bv;
1813 float t1x = (bv[
data->index[0]] -
data->ray.origin[0]) *
data->idot_axis[0];
1814 float t2x = (bv[
data->index[1]] -
data->ray.origin[0]) *
data->idot_axis[0];
1815 float t1y = (bv[
data->index[2]] -
data->ray.origin[1]) *
data->idot_axis[1];
1816 float t2y = (bv[
data->index[3]] -
data->ray.origin[1]) *
data->idot_axis[1];
1817 float t1z = (bv[
data->index[4]] -
data->ray.origin[2]) *
data->idot_axis[2];
1818 float t2z = (bv[
data->index[5]] -
data->ray.origin[2]) *
data->idot_axis[2];
1820 if ((t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) ||
1821 (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) ||
1822 (t1x >
data->hit.dist || t1y >
data->hit.dist || t1z >
data->hit.dist)) {
1825 return max_fff(t1x, t1y, t1z);
1837 if (dist >=
data->hit.dist) {
1841 if (
node->totnode == 0) {
1842 if (
data->callback) {
1847 data->hit.dist = dist;
1853 if (
data->ray_dot_axis[
node->main_axis] > 0.0f) {
1854 for (i = 0; i !=
node->totnode; i++) {
1859 for (i =
node->totnode - 1; i >= 0; i--) {
1878 if (dist >=
data->hit.dist) {
1882 if (
node->totnode == 0) {
1884 dist =
data->hit.dist;
1886 data->hit.index = -1;
1887 data->hit.dist = dist;
1891 if (
data->ray_dot_axis[
node->main_axis] > 0.0f) {
1892 for (i = 0; i !=
node->totnode; i++) {
1897 for (i =
node->totnode - 1; i >= 0; i--) {
1908 for (i = 0; i < 3; i++) {
1911 if (
fabsf(
data->ray_dot_axis[i]) < FLT_EPSILON) {
1912 data->ray_dot_axis[i] = 0.0f;
1914 data->idot_axis[i] = FLT_MAX;
1917 data->idot_axis[i] = 1.0f /
data->ray_dot_axis[i];
1920 data->index[2 * i] =
data->idot_axis[i] < 0.0f ? 1 : 0;
1921 data->index[2 * i + 1] = 1 -
data->index[2 * i];
1922 data->index[2 * i] += 2 * i;
1923 data->index[2 * i + 1] += 2 * i;
1926 #ifdef USE_KDOPBVH_WATERTIGHT
1929 data->ray.isect_precalc = &
data->isect_precalc;
1956 data.userdata = userdata;
1960 data.ray.radius = radius;
1965 memcpy(&
data.hit, hit,
sizeof(*hit));
1968 data.hit.index = -1;
1978 memcpy(hit, &
data.hit,
sizeof(*hit));
1981 return data.hit.index;
1997 const float light_start[3],
1998 const float light_end[3],
2009 data.ray.radius = 0.0;
2050 data.userdata = userdata;
2054 data.ray.radius = radius;
2058 data.hit.index = -1;
2059 data.hit.dist = hit_dist;
2102 if (
node->totnode == 0) {
2107 co[0] =
node->bv[0];
2108 co[1] =
node->bv[2];
2109 co[2] =
node->bv[4];
2114 for (i = 0; i !=
node->totnode; i++) {
2117 if (dist_sq < data->radius_sq) {
2119 if (
node->children[i]->totnode == 0) {
2121 data->callback(
data->userdata,
node->children[i]->index,
data->center, dist_sq);
2139 data.radius_sq = radius * radius;
2143 data.userdata = userdata;
2148 if (dist_sq <
data.radius_sq) {
2172 if (
node->totnode == 0) {
2173 if (
data->callback) {
2180 (
float[3]){node->bv[0], node->bv[2], node->bv[4]},
2181 (
float[3]){node->bv[1], node->bv[3], node->bv[5]},
2182 data->closest_axis);
2187 if (
data->closest_axis[
node->main_axis]) {
2188 for (
int i = 0; i !=
node->totnode; i++) {
2189 const float *bv =
node->children[i]->bv;
2192 (
float[3]){bv[0], bv[2], bv[4]},
2193 (
float[3]){bv[1], bv[3], bv[5]},
2194 data->closest_axis) <=
data->nearest.dist_sq) {
2200 for (
int i =
node->totnode; i--;) {
2201 const float *bv =
node->children[i]->bv;
2204 (
float[3]){bv[0], bv[2], bv[4]},
2205 (
float[3]){bv[1], bv[3], bv[5]},
2206 data->closest_axis) <=
data->nearest.dist_sq) {
2217 if (
node->totnode == 0) {
2218 if (
data->callback) {
2223 data->clip_plane_len,
2230 (
float[3]){node->bv[0], node->bv[2], node->bv[4]},
2231 (
float[3]){node->bv[1], node->bv[3], node->bv[5]},
2232 data->closest_axis);
2237 if (
data->closest_axis[
node->main_axis]) {
2238 for (
int i = 0; i !=
node->totnode; i++) {
2239 const float *bv =
node->children[i]->bv;
2240 const float bb_min[3] = {bv[0], bv[2], bv[4]};
2241 const float bb_max[3] = {bv[1], bv[3], bv[5]};
2244 data->clip_plane,
data->clip_plane_len, bb_min, bb_max);
2248 data->nearest.dist_sq) {
2260 for (
int i =
node->totnode; i--;) {
2261 const float *bv =
node->children[i]->bv;
2262 const float bb_min[3] = {bv[0], bv[2], bv[4]};
2263 const float bb_max[3] = {bv[1], bv[3], bv[5]};
2266 data->clip_plane,
data->clip_plane_len, bb_min, bb_max);
2270 data->nearest.dist_sq) {
2285 float projmat[4][4],
2288 float clip_plane[6][4],
2300 data.userdata = userdata;
2303 data.clip_plane_len = clip_plane_len;
2304 for (
int i = 0; i <
data.clip_plane_len; i++) {
2309 data.clip_plane_len = 1;
2314 memcpy(&
data.nearest, nearest,
sizeof(*nearest));
2317 data.nearest.index = -1;
2318 data.nearest.dist_sq = FLT_MAX;
2321 const float bb_min[3] = {root->
bv[0], root->
bv[2], root->
bv[4]};
2322 const float bb_max[3] = {root->
bv[1], root->
bv[3], root->
bv[5]};
2326 if (isect_type != 0 &&
2328 data.nearest.dist_sq) {
2329 if (isect_type == 1) {
2339 memcpy(nearest, &
data.nearest,
sizeof(*nearest));
2342 return data.nearest.index;
2368 if (
node->totnode == 0) {
2376 for (
int i = 0; i !=
node->totnode; i++) {
2386 for (
int i =
node->totnode - 1; i >= 0; i--) {
2418 BVHTree_WalkData walk_data = {walk_parent_cb, walk_leaf_cb, walk_order_cb, userdata};
typedef float(TangentPoint)[2]
#define BLI_array_alloca(arr, realsize)
A min-heap / priority queue ADT.
void BLI_heapsimple_free(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp) ATTR_NONNULL(1)
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)
HeapSimple * BLI_heapsimple_new_ex(unsigned int tot_reserve) ATTR_WARN_UNUSED_RESULT
void BLI_heapsimple_insert(HeapSimple *heap, float value, void *ptr) ATTR_NONNULL(1)
static void non_recursive_bvh_div_nodes(const BVHTree *tree, BVHNode *branches_array, BVHNode **leafs_array, int num_leafs)
int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata)
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)
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)
int BLI_bvhtree_find_nearest_projected(BVHTree *tree, float projmat[4][4], float winsize[2], float mval[2], float clip_plane[6][4], int clip_plane_len, BVHTreeNearest *nearest, BVHTree_NearestProjectedCallback callback, void *userdata)
struct BVHNearestProjectedData BVHNearestProjectedData
struct BVHIntersectPlaneData BVHIntersectPlaneData
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_find_nearest_first(BVHTree *tree, const float co[3], const float dist_sq, BVHTree_NearestPointCallback callback, void *userdata)
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
BVHTreeOverlap * BLI_bvhtree_overlap_ex(const BVHTree *tree1, const BVHTree *tree2, uint *r_overlap_tot, BVHTree_OverlapCallback callback, void *userdata, const uint max_interactions, const int flag)
static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNode *node)
int BLI_bvhtree_find_nearest_ex(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata, int flag)
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)
int * BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_tot)
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)
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
static void heap_find_nearest_inner(BVHNearestData *data, HeapSimple *heap, BVHNode *node)
void BLI_bvhtree_update_tree(BVHTree *tree)
int BLI_bvhtree_ray_cast_ex(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata, int flag)
static bool isect_aabb_v3(BVHNode *node, const float co[3])
MINLINE axis_t min_axis(axis_t a, axis_t b)
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
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 int bvh_partition(BVHNode **a, int lo, int hi, BVHNode *x, int axis)
static void node_join(BVHTree *tree, BVHNode *node)
struct BVHTree_WalkData BVHTree_WalkData
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_walk_dfs(BVHTree *tree, BVHTree_WalkParentCallback walk_parent_cb, BVHTree_WalkLeafCallback walk_leaf_cb, BVHTree_WalkOrderCallback walk_order_cb, 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]
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)
static void split_leafs(BVHNode **leafs_array, const int nth[], const int partitions, const int split_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])
void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3])
BVHTreeOverlap * BLI_bvhtree_overlap(const BVHTree *tree1, const BVHTree *tree2, uint *r_overlap_tot, BVHTree_OverlapCallback callback, void *userdata)
static int implicit_needed_branches(int tree_type, int leafs)
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)
BLI_STATIC_ASSERT((sizeof(void *)==8 &&sizeof(BVHTree)<=48)||(sizeof(void *)==4 &&sizeof(BVHTree)<=32), "over sized")
static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node)
int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
static void bvhtree_overlap_task_cb(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict UNUSED(tls))
struct BVHBuildHelper BVHBuildHelper
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)
int BLI_bvhtree_find_nearest(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)
@ BVH_NEAREST_OPTIMAL_ORDER
@ BVH_OVERLAP_USE_THREADING
@ BVH_OVERLAP_RETURN_PAIRS
#define BVH_RAYCAST_DIST_MAX
#define BVH_RAYCAST_DEFAULT
bool(* BVHTree_WalkLeafCallback)(const BVHTreeAxisRange *bounds, int index, void *userdata)
bool(* BVHTree_WalkOrderCallback)(const BVHTreeAxisRange *bounds, char axis, void *userdata)
void(* BVHTree_RayCastCallback)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
bool(* BVHTree_WalkParentCallback)(const BVHTreeAxisRange *bounds, void *userdata)
void(* BVHTree_NearestProjectedCallback)(void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, const float(*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest)
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)
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])
void planes_from_projmat(const float mat[4][4], float left[4], float right[4], float top[4], float bottom[4], float near[4], float far[4])
int isect_aabb_planes_v3(const float(*planes)[4], const int totplane, const float bbmin[3], const float bbmax[3])
MINLINE void copy_v4_v4(float r[4], const float a[4])
MINLINE float normalize_v3(float r[3])
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])
void * BLI_stack_push_r(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
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()
#define BLI_stack_new(esize, descr)
Strict compiler flags for areas of code we want to ensure don't do conversions without us knowing abo...
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble right
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
Read Guarded memory(de)allocation.
DEGForeachIDComponentCallback callback
void(* MEM_freeN)(void *vmemh)
size_t(* MEM_allocN_len)(const void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
int branches_on_level[32]
const BVHBuildHelper * data
struct BLI_Stack * intersect
BVHTree_NearestPointCallback callback
struct DistProjectedAABBPrecalc precalc
BVHTree_NearestProjectedCallback callback
struct BVHNode ** children
struct BLI_Stack * overlap
BVHOverlapData_Shared * shared
BVHTree_RayCastCallback callback
BVHTree_WalkOrderCallback walk_order_cb
BVHTree_WalkLeafCallback walk_leaf_cb
BVHTree_WalkParentCallback walk_parent_cb
BVHTree_RangeQuery callback
__forceinline ssef low(const avxf &a)
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)