Blender  V2.93
BLI_kdopbvh.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2006 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
41 #include "MEM_guardedalloc.h"
42 
43 #include "BLI_alloca.h"
44 #include "BLI_heap_simple.h"
45 #include "BLI_kdopbvh.h"
46 #include "BLI_math.h"
47 #include "BLI_stack.h"
48 #include "BLI_task.h"
49 #include "BLI_utildefines.h"
50 
51 #include "BLI_strict_flags.h"
52 
53 /* used for iterative_raycast */
54 // #define USE_SKIP_LINKS
55 
56 /* Use to print balanced output. */
57 // #define USE_PRINT_TREE
58 
59 /* Check tree is valid. */
60 // #define USE_VERIFY_TREE
61 
62 #define MAX_TREETYPE 32
63 
64 /* Setting zero so we can catch bugs in BLI_task/KDOPBVH.
65  * TODO(sergey): Deduplicate the limits with PBVH from BKE.
66  */
67 #ifdef DEBUG
68 # define KDOPBVH_THREAD_LEAF_THRESHOLD 0
69 #else
70 # define KDOPBVH_THREAD_LEAF_THRESHOLD 1024
71 #endif
72 
73 /* -------------------------------------------------------------------- */
77 typedef unsigned char axis_t;
78 
79 typedef struct BVHNode {
80  struct BVHNode **children;
81  struct BVHNode *parent; /* some user defined traversed need that */
82 #ifdef USE_SKIP_LINKS
83  struct BVHNode *skip[2];
84 #endif
85  float *bv; /* Bounding volume of all nodes, max 13 axis */
86  int index; /* face, edge, vertex index */
87  char totnode; /* how many nodes are used, used for speedup */
88  char main_axis; /* Axis used to split this node */
90 
91 /* keep under 26 bytes for speed purposes */
92 struct BVHTree {
94  BVHNode *nodearray; /* pre-alloc branch nodes */
95  BVHNode **nodechild; /* pre-alloc children for nodes */
96  float *nodebv; /* pre-alloc bounding-volumes for nodes */
97  float epsilon; /* Epsilon is used for inflation of the K-DOP. */
98  int totleaf; /* leafs */
99  int totbranch;
100  axis_t start_axis, stop_axis; /* bvhtree_kdop_axes array indices according to axis */
101  axis_t axis; /* kdop type (6 => OBB, 7 => AABB, ...) */
102  char tree_type; /* type of tree (4 => quadtree) */
103 };
104 
105 /* optimization, ensure we stay small */
106 BLI_STATIC_ASSERT((sizeof(void *) == 8 && sizeof(BVHTree) <= 48) ||
107  (sizeof(void *) == 4 && sizeof(BVHTree) <= 32),
108  "over sized")
109 
110 /* avoid duplicating vars in BVHOverlapData_Thread */
111 typedef struct BVHOverlapData_Shared {
112  const BVHTree *tree1, *tree2;
113  axis_t start_axis, stop_axis;
114 
115  /* use for callbacks */
117  void *userdata;
119 
120 typedef struct BVHOverlapData_Thread {
122  struct BLI_Stack *overlap; /* store BVHTreeOverlap */
124  /* use for callbacks */
125  int thread;
127 
128 typedef struct BVHNearestData {
129  const BVHTree *tree;
130  const float *co;
132  void *userdata;
133  float proj[13]; /* coordinates projection over axis */
135 
137 
138 typedef struct BVHRayCastData {
139  const BVHTree *tree;
140 
142  void *userdata;
143 
145 
146 #ifdef USE_KDOPBVH_WATERTIGHT
147  struct IsectRayPrecalc isect_precalc;
148 #endif
149 
150  /* initialized by bvhtree_ray_cast_data_precalc */
151  float ray_dot_axis[13];
152  float idot_axis[13];
153  int index[6];
154 
157 
158 typedef struct BVHNearestProjectedData {
159  const BVHTree *tree;
161  bool closest_axis[3];
162  float clip_plane[6][4];
165  void *userdata;
167 
169 
170 typedef struct BVHIntersectPlaneData {
171  const BVHTree *tree;
172  float plane[4];
173  struct BLI_Stack *intersect; /* Store indexes. */
175 
186 const float bvhtree_kdop_axes[13][3] = {
187  {1.0, 0, 0},
188  {0, 1.0, 0},
189  {0, 0, 1.0},
190  {1.0, 1.0, 1.0},
191  {1.0, -1.0, 1.0},
192  {1.0, 1.0, -1.0},
193  {1.0, -1.0, -1.0},
194  {1.0, 1.0, 0},
195  {1.0, 0, 1.0},
196  {0, 1.0, 1.0},
197  {1.0, -1.0, 0},
198  {1.0, 0, -1.0},
199  {0, 1.0, -1.0},
200 };
201 
202 /* Used to correct the epsilon and thus match the overlap distance. */
203 static const float bvhtree_kdop_axes_length[13] = {
204  1.0f,
205  1.0f,
206  1.0f,
207  1.7320508075688772f,
208  1.7320508075688772f,
209  1.7320508075688772f,
210  1.7320508075688772f,
211  1.4142135623730951f,
212  1.4142135623730951f,
213  1.4142135623730951f,
214  1.4142135623730951f,
215  1.4142135623730951f,
216  1.4142135623730951f,
217 };
218 
219 /* -------------------------------------------------------------------- */
224 {
225  return (a < b) ? a : b;
226 }
227 #if 0
228 MINLINE axis_t max_axis(axis_t a, axis_t b)
229 {
230  return (b < a) ? a : b;
231 }
232 #endif
233 
241 static void node_minmax_init(const BVHTree *tree, BVHNode *node)
242 {
243  axis_t axis_iter;
244  float(*bv)[2] = (float(*)[2])node->bv;
245 
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;
249  }
250 }
251 
254 /* -------------------------------------------------------------------- */
261 static void bvh_insertionsort(BVHNode **a, int lo, int hi, int axis)
262 {
263  int i, j;
264  BVHNode *t;
265  for (i = lo; i < hi; i++) {
266  j = i;
267  t = a[i];
268  while ((j != lo) && (t->bv[axis] < (a[j - 1])->bv[axis])) {
269  a[j] = a[j - 1];
270  j--;
271  }
272  a[j] = t;
273  }
274 }
275 
276 static int bvh_partition(BVHNode **a, int lo, int hi, BVHNode *x, int axis)
277 {
278  int i = lo, j = hi;
279  while (1) {
280  while (a[i]->bv[axis] < x->bv[axis]) {
281  i++;
282  }
283  j--;
284  while (x->bv[axis] < a[j]->bv[axis]) {
285  j--;
286  }
287  if (!(i < j)) {
288  return i;
289  }
290  SWAP(BVHNode *, a[i], a[j]);
291  i++;
292  }
293 }
294 
295 /* returns Sortable */
296 static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis)
297 {
298  if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) {
299  if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
300  return a[mid];
301  }
302  if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
303  return a[hi];
304  }
305  return a[lo];
306  }
307 
308  if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
309  if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
310  return a[lo];
311  }
312  return a[hi];
313  }
314  return a[mid];
315 }
316 
321 static void partition_nth_element(BVHNode **a, int begin, int end, const int n, const int axis)
322 {
323  while (end - begin > 3) {
324  const int cut = bvh_partition(
325  a, begin, end, bvh_medianof3(a, begin, (begin + end) / 2, end - 1, axis), axis);
326  if (cut <= n) {
327  begin = cut;
328  }
329  else {
330  end = cut;
331  }
332  }
333  bvh_insertionsort(a, begin, end, axis);
334 }
335 
336 #ifdef USE_SKIP_LINKS
337 static void build_skip_links(BVHTree *tree, BVHNode *node, BVHNode *left, BVHNode *right)
338 {
339  int i;
340 
341  node->skip[0] = left;
342  node->skip[1] = right;
343 
344  for (i = 0; i < node->totnode; i++) {
345  if (i + 1 < node->totnode) {
346  build_skip_links(tree, node->children[i], left, node->children[i + 1]);
347  }
348  else {
349  build_skip_links(tree, node->children[i], left, right);
350  }
351 
352  left = node->children[i];
353  }
354 }
355 #endif
356 
357 /*
358  * BVHTree bounding volumes functions
359  */
360 static void create_kdop_hull(
361  const BVHTree *tree, BVHNode *node, const float *co, int numpoints, int moving)
362 {
363  float newminmax;
364  float *bv = node->bv;
365  int k;
366  axis_t axis_iter;
367 
368  /* Don't initialize bounds for the moving case */
369  if (!moving) {
371  }
372 
373  for (k = 0; k < numpoints; k++) {
374  /* for all Axes. */
375  for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
376  newminmax = dot_v3v3(&co[k * 3], bvhtree_kdop_axes[axis_iter]);
377  if (newminmax < bv[2 * axis_iter]) {
378  bv[2 * axis_iter] = newminmax;
379  }
380  if (newminmax > bv[(2 * axis_iter) + 1]) {
381  bv[(2 * axis_iter) + 1] = newminmax;
382  }
383  }
384  }
385 }
386 
390 static void refit_kdop_hull(const BVHTree *tree, BVHNode *node, int start, int end)
391 {
392  float newmin, newmax;
393  float *__restrict bv = node->bv;
394  int j;
395  axis_t axis_iter;
396 
398 
399  for (j = start; j < end; j++) {
400  float *__restrict node_bv = tree->nodes[j]->bv;
401 
402  /* for all Axes. */
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;
407  }
408 
409  newmax = node_bv[(2 * axis_iter) + 1];
410  if ((newmax > bv[(2 * axis_iter) + 1])) {
411  bv[(2 * axis_iter) + 1] = newmax;
412  }
413  }
414  }
415 }
416 
420 static char get_largest_axis(const float *bv)
421 {
422  float middle_point[3];
423 
424  middle_point[0] = (bv[1]) - (bv[0]); /* x axis */
425  middle_point[1] = (bv[3]) - (bv[2]); /* y axis */
426  middle_point[2] = (bv[5]) - (bv[4]); /* z axis */
427  if (middle_point[0] > middle_point[1]) {
428  if (middle_point[0] > middle_point[2]) {
429  return 1; /* max x axis */
430  }
431  return 5; /* max z axis */
432  }
433  if (middle_point[1] > middle_point[2]) {
434  return 3; /* max y axis */
435  }
436  return 5; /* max z axis */
437 }
438 
443 {
444  int i;
445  axis_t axis_iter;
446 
448 
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++) {
452  /* update minimum */
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)];
455  }
456 
457  /* update maximum */
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];
460  }
461  }
462  }
463  else {
464  break;
465  }
466  }
467 }
468 
469 #ifdef USE_PRINT_TREE
470 
475 static void bvhtree_print_tree(BVHTree *tree, BVHNode *node, int depth)
476 {
477  int i;
478  axis_t axis_iter;
479 
480  for (i = 0; i < depth; i++) {
481  printf(" ");
482  }
483  printf(" - %d (%ld): ", node->index, (long int)(node - tree->nodearray));
484  for (axis_iter = (axis_t)(2 * tree->start_axis); axis_iter < (axis_t)(2 * tree->stop_axis);
485  axis_iter++) {
486  printf("%.3f ", node->bv[axis_iter]);
487  }
488  printf("\n");
489 
490  for (i = 0; i < tree->tree_type; i++) {
491  if (node->children[i]) {
492  bvhtree_print_tree(tree, node->children[i], depth + 1);
493  }
494  }
495 }
496 
497 static void bvhtree_info(BVHTree *tree)
498 {
499  printf("BVHTree Info: tree_type = %d, axis = %d, epsilon = %f\n",
500  tree->tree_type,
501  tree->axis,
502  tree->epsilon);
503  printf("nodes = %d, branches = %d, leafs = %d\n",
504  tree->totbranch + tree->totleaf,
505  tree->totbranch,
506  tree->totleaf);
507  printf(
508  "Memory per node = %ubytes\n",
509  (uint)(sizeof(BVHNode) + sizeof(BVHNode *) * tree->tree_type + sizeof(float) * tree->axis));
510  printf("BV memory = %ubytes\n", (uint)MEM_allocN_len(tree->nodebv));
511 
512  printf("Total memory = %ubytes\n",
513  (uint)(sizeof(BVHTree) + MEM_allocN_len(tree->nodes) + MEM_allocN_len(tree->nodearray) +
514  MEM_allocN_len(tree->nodechild) + MEM_allocN_len(tree->nodebv)));
515 
516  bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0);
517 }
518 #endif /* USE_PRINT_TREE */
519 
520 #ifdef USE_VERIFY_TREE
521 
522 static void bvhtree_verify(BVHTree *tree)
523 {
524  int i, j, check = 0;
525 
526  /* check the pointer list */
527  for (i = 0; i < tree->totleaf; i++) {
528  if (tree->nodes[i]->parent == NULL) {
529  printf("Leaf has no parent: %d\n", i);
530  }
531  else {
532  for (j = 0; j < tree->tree_type; j++) {
533  if (tree->nodes[i]->parent->children[j] == tree->nodes[i]) {
534  check = 1;
535  }
536  }
537  if (!check) {
538  printf("Parent child relationship doesn't match: %d\n", i);
539  }
540  check = 0;
541  }
542  }
543 
544  /* check the leaf list */
545  for (i = 0; i < tree->totleaf; i++) {
546  if (tree->nodearray[i].parent == NULL) {
547  printf("Leaf has no parent: %d\n", i);
548  }
549  else {
550  for (j = 0; j < tree->tree_type; j++) {
551  if (tree->nodearray[i].parent->children[j] == &tree->nodearray[i]) {
552  check = 1;
553  }
554  }
555  if (!check) {
556  printf("Parent child relationship doesn't match: %d\n", i);
557  }
558  check = 0;
559  }
560  }
561 
562  printf("branches: %d, leafs: %d, total: %d\n",
563  tree->totbranch,
564  tree->totleaf,
565  tree->totbranch + tree->totleaf);
566 }
567 #endif /* USE_VERIFY_TREE */
568 
569 /* Helper data and structures to build a min-leaf generalized implicit tree
570  * This code can be easily reduced
571  * (basically this is only method to calculate pow(k, n) in O(1).. and stuff like that) */
572 typedef struct BVHBuildHelper {
574  int totleafs;
575 
580 
583 
585 
587 {
588  int depth = 0;
589  int remain;
590  int nnodes;
591 
592  data->totleafs = tree->totleaf;
593  data->tree_type = tree->tree_type;
594 
595  /* Calculate the smallest tree_type^n such that tree_type^n >= num_leafs */
596  for (data->leafs_per_child[0] = 1; data->leafs_per_child[0] < data->totleafs;
597  data->leafs_per_child[0] *= data->tree_type) {
598  /* pass */
599  }
600 
601  data->branches_on_level[0] = 1;
602 
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;
606  }
607 
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;
611 }
612 
616 static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, const int child_index)
617 {
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;
621  }
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];
625  }
626  return data->remain_leafs;
627 }
628 
658 /* This functions returns the number of branches needed to have the requested number of leafs. */
659 static int implicit_needed_branches(int tree_type, int leafs)
660 {
661  return max_ii(1, (leafs + tree_type - 3) / (tree_type - 1));
662 }
663 
676 static void split_leafs(BVHNode **leafs_array,
677  const int nth[],
678  const int partitions,
679  const int split_axis)
680 {
681  int i;
682  for (i = 0; i < partitions - 1; i++) {
683  if (nth[i] >= nth[partitions]) {
684  break;
685  }
686 
687  partition_nth_element(leafs_array, nth[i], nth[partitions], nth[i + 1], split_axis);
688  }
689 }
690 
691 typedef struct BVHDivNodesData {
692  const BVHTree *tree;
695 
698 
700 
701  int depth;
702  int i;
705 
706 static void non_recursive_bvh_div_nodes_task_cb(void *__restrict userdata,
707  const int j,
708  const TaskParallelTLS *__restrict UNUSED(tls))
709 {
710  BVHDivNodesData *data = userdata;
711 
712  int k;
713  const int parent_level_index = j - data->i;
714  BVHNode *parent = &data->branches_array[j];
715  int nth_positions[MAX_TREETYPE + 1];
716  char split_axis;
717 
718  int parent_leafs_begin = implicit_leafs_index(data->data, data->depth, parent_level_index);
719  int parent_leafs_end = implicit_leafs_index(data->data, data->depth, parent_level_index + 1);
720 
721  /* This calculates the bounding box of this branch
722  * and chooses the largest axis as the axis to divide leafs */
723  refit_kdop_hull(data->tree, parent, parent_leafs_begin, parent_leafs_end);
724  split_axis = get_largest_axis(parent->bv);
725 
726  /* Save split axis (this can be used on ray-tracing to speedup the query time) */
727  parent->main_axis = split_axis / 2;
728 
729  /* Split the children along the split_axis, note: its not needed to sort the whole leafs array
730  * Only to assure that the elements are partitioned on a way that each child takes the elements
731  * it would take in case the whole array was sorted.
732  * Split_leafs takes care of that "sort" problem. */
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;
737  /* child level index */
738  const int child_level_index = child_index - data->first_of_next_level;
739  nth_positions[k] = implicit_leafs_index(data->data, data->depth + 1, child_level_index);
740  }
741 
742  split_leafs(data->leafs_array, nth_positions, data->tree_type, split_axis);
743 
744  /* Setup children and totnode counters
745  * Not really needed but currently most of BVH code
746  * relies on having an explicit children structure */
747  for (k = 0; k < data->tree_type; k++) {
748  const int child_index = j * data->tree_type + data->tree_offset + k;
749  /* child level index */
750  const int child_level_index = child_index - data->first_of_next_level;
751 
752  const int child_leafs_begin = implicit_leafs_index(
753  data->data, data->depth + 1, child_level_index);
754  const int child_leafs_end = implicit_leafs_index(
755  data->data, data->depth + 1, child_level_index + 1);
756 
757  if (child_leafs_end - child_leafs_begin > 1) {
758  parent->children[k] = &data->branches_array[child_index];
759  parent->children[k]->parent = parent;
760  }
761  else if (child_leafs_end - child_leafs_begin == 1) {
762  parent->children[k] = data->leafs_array[child_leafs_begin];
763  parent->children[k]->parent = parent;
764  }
765  else {
766  break;
767  }
768  }
769  parent->totnode = (char)k;
770 }
771 
791  BVHNode *branches_array,
792  BVHNode **leafs_array,
793  int num_leafs)
794 {
795  int i;
796 
797  const int tree_type = tree->tree_type;
798  /* this value is 0 (on binary trees) and negative on the others */
799  const int tree_offset = 2 - tree->tree_type;
800 
801  const int num_branches = implicit_needed_branches(tree_type, num_leafs);
802 
804  int depth;
805 
806  {
807  /* set parent from root node to NULL */
808  BVHNode *root = &branches_array[1];
809  root->parent = NULL;
810 
811  /* Most of bvhtree code relies on 1-leaf trees having at least one branch
812  * We handle that special case here */
813  if (num_leafs == 1) {
814  refit_kdop_hull(tree, root, 0, num_leafs);
815  root->main_axis = get_largest_axis(root->bv) / 2;
816  root->totnode = 1;
817  root->children[0] = leafs_array[0];
818  root->children[0]->parent = root;
819  return;
820  }
821  }
822 
824 
825  BVHDivNodesData cb_data = {
826  .tree = tree,
827  .branches_array = branches_array,
828  .leafs_array = leafs_array,
829  .tree_type = tree_type,
830  .tree_offset = tree_offset,
831  .data = &data,
832  .first_of_next_level = 0,
833  .depth = 0,
834  .i = 0,
835  };
836 
837  /* Loop tree levels (log N) loops */
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;
840  /* index of last branch on this level */
841  const int i_stop = min_ii(first_of_next_level, num_branches + 1);
842 
843  /* Loop all branches on this level */
844  cb_data.first_of_next_level = first_of_next_level;
845  cb_data.i = i;
846  cb_data.depth = depth;
847 
848  if (true) {
849  TaskParallelSettings settings;
851  settings.use_threading = (num_leafs > KDOPBVH_THREAD_LEAF_THRESHOLD);
852  BLI_task_parallel_range(i, i_stop, &cb_data, non_recursive_bvh_div_nodes_task_cb, &settings);
853  }
854  else {
855  /* Less hassle for debugging. */
856  TaskParallelTLS tls = {0};
857  for (int i_task = i; i_task < i_stop; i_task++) {
858  non_recursive_bvh_div_nodes_task_cb(&cb_data, i_task, &tls);
859  }
860  }
861  }
862 }
863 
866 /* -------------------------------------------------------------------- */
873 BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
874 {
875  BVHTree *tree;
876  int numnodes, i;
877 
878  BLI_assert(tree_type >= 2 && tree_type <= MAX_TREETYPE);
879 
880  tree = MEM_callocN(sizeof(BVHTree), "BVHTree");
881 
882  /* tree epsilon must be >= FLT_EPSILON
883  * so that tangent rays can still hit a bounding volume..
884  * this bug would show up when casting a ray aligned with a kdop-axis
885  * and with an edge of 2 faces */
886  epsilon = max_ff(FLT_EPSILON, epsilon);
887 
888  if (tree) {
889  tree->epsilon = epsilon;
890  tree->tree_type = tree_type;
891  tree->axis = axis;
892 
893  if (axis == 26) {
894  tree->start_axis = 0;
895  tree->stop_axis = 13;
896  }
897  else if (axis == 18) {
898  tree->start_axis = 7;
899  tree->stop_axis = 13;
900  }
901  else if (axis == 14) {
902  tree->start_axis = 0;
903  tree->stop_axis = 7;
904  }
905  else if (axis == 8) { /* AABB */
906  tree->start_axis = 0;
907  tree->stop_axis = 4;
908  }
909  else if (axis == 6) { /* OBB */
910  tree->start_axis = 0;
911  tree->stop_axis = 3;
912  }
913  else {
914  /* should never happen! */
915  BLI_assert(0);
916 
917  goto fail;
918  }
919 
920  /* Allocate arrays */
921  numnodes = maxsize + implicit_needed_branches(tree_type, maxsize) + tree_type;
922 
923  tree->nodes = MEM_callocN(sizeof(BVHNode *) * (size_t)numnodes, "BVHNodes");
924  tree->nodebv = MEM_callocN(sizeof(float) * (size_t)(axis * numnodes), "BVHNodeBV");
925  tree->nodechild = MEM_callocN(sizeof(BVHNode *) * (size_t)(tree_type * numnodes), "BVHNodeBV");
926  tree->nodearray = MEM_callocN(sizeof(BVHNode) * (size_t)numnodes, "BVHNodeArray");
927 
928  if (UNLIKELY((!tree->nodes) || (!tree->nodebv) || (!tree->nodechild) || (!tree->nodearray))) {
929  goto fail;
930  }
931 
932  /* link the dynamic bv and child links */
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];
936  }
937  }
938  return tree;
939 
940 fail:
942  return NULL;
943 }
944 
946 {
947  if (tree) {
948  MEM_SAFE_FREE(tree->nodes);
949  MEM_SAFE_FREE(tree->nodearray);
950  MEM_SAFE_FREE(tree->nodebv);
951  MEM_SAFE_FREE(tree->nodechild);
952  MEM_freeN(tree);
953  }
954 }
955 
957 {
958  BVHNode **leafs_array = tree->nodes;
959 
960  /* This function should only be called once
961  * (some big bug goes here if its being called more than once per tree) */
962  BLI_assert(tree->totbranch == 0);
963 
964  /* Build the implicit tree */
966  tree, tree->nodearray + (tree->totleaf - 1), leafs_array, tree->totleaf);
967 
968  /* current code expects the branches to be linked to the nodes array
969  * we perform that linkage here */
970  tree->totbranch = implicit_needed_branches(tree->tree_type, tree->totleaf);
971  for (int i = 0; i < tree->totbranch; i++) {
972  tree->nodes[tree->totleaf + i] = &tree->nodearray[tree->totleaf + i];
973  }
974 
975 #ifdef USE_SKIP_LINKS
976  build_skip_links(tree, tree->nodes[tree->totleaf], NULL, NULL);
977 #endif
978 
979 #ifdef USE_VERIFY_TREE
980  bvhtree_verify(tree);
981 #endif
982 
983 #ifdef USE_PRINT_TREE
984  bvhtree_info(tree);
985 #endif
986 }
987 
988 static void bvhtree_node_inflate(const BVHTree *tree, BVHNode *node, const float dist)
989 {
990  axis_t axis_iter;
991  for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
992  float dist_corrected = dist * bvhtree_kdop_axes_length[axis_iter];
993  node->bv[(2 * axis_iter)] -= dist_corrected; /* minimum */
994  node->bv[(2 * axis_iter) + 1] += dist_corrected; /* maximum */
995  }
996 }
997 
998 void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
999 {
1000  BVHNode *node = NULL;
1001 
1002  /* insert should only possible as long as tree->totbranch is 0 */
1003  BLI_assert(tree->totbranch <= 0);
1004  BLI_assert((size_t)tree->totleaf < MEM_allocN_len(tree->nodes) / sizeof(*(tree->nodes)));
1005 
1006  node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]);
1007  tree->totleaf++;
1008 
1009  create_kdop_hull(tree, node, co, numpoints, 0);
1010  node->index = index;
1011 
1012  /* inflate the bv with some epsilon */
1013  bvhtree_node_inflate(tree, node, tree->epsilon);
1014 }
1015 
1016 /* call before BLI_bvhtree_update_tree() */
1018  BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
1019 {
1020  BVHNode *node = NULL;
1021 
1022  /* check if index exists */
1023  if (index > tree->totleaf) {
1024  return false;
1025  }
1026 
1027  node = tree->nodearray + index;
1028 
1029  create_kdop_hull(tree, node, co, numpoints, 0);
1030 
1031  if (co_moving) {
1032  create_kdop_hull(tree, node, co_moving, numpoints, 1);
1033  }
1034 
1035  /* inflate the bv with some epsilon */
1036  bvhtree_node_inflate(tree, node, tree->epsilon);
1037 
1038  return true;
1039 }
1040 
1045 {
1046  /* Update bottom=>top
1047  * TRICKY: the way we build the tree all the children have an index greater than the parent
1048  * This allows us todo a bottom up update by starting on the bigger numbered branch. */
1049 
1050  BVHNode **root = tree->nodes + tree->totleaf;
1051  BVHNode **index = tree->nodes + tree->totleaf + tree->totbranch - 1;
1052 
1053  for (; index >= root; index--) {
1054  node_join(tree, *index);
1055  }
1056 }
1062 {
1063  return tree->totleaf;
1064 }
1065 
1070 {
1071  return tree->tree_type;
1072 }
1073 
1075 {
1076  return tree->epsilon;
1077 }
1078 
1082 void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3])
1083 {
1084  BVHNode *root = tree->nodes[tree->totleaf];
1085  if (root != NULL) {
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]};
1088  copy_v3_v3(r_bb_min, bb_min);
1089  copy_v3_v3(r_bb_max, bb_max);
1090  }
1091  else {
1092  BLI_assert(false);
1093  zero_v3(r_bb_min);
1094  zero_v3(r_bb_max);
1095  }
1096 }
1097 
1100 /* -------------------------------------------------------------------- */
1107 static bool tree_overlap_test(const BVHNode *node1,
1108  const BVHNode *node2,
1109  axis_t start_axis,
1110  axis_t stop_axis)
1111 {
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);
1115 
1116  /* test all axis if min + max overlap */
1117  for (; bv1 != bv1_end; bv1 += 2, bv2 += 2) {
1118  if ((bv1[0] > bv2[1]) || (bv2[0] > bv1[1])) {
1119  return 0;
1120  }
1121  }
1122 
1123  return 1;
1124 }
1125 
1127  const BVHNode *node1,
1128  const BVHNode *node2)
1129 {
1130  BVHOverlapData_Shared *data = data_thread->shared;
1131  int j;
1132 
1133  if (tree_overlap_test(node1, node2, data->start_axis, data->stop_axis)) {
1134  /* check if node1 is a leaf */
1135  if (!node1->totnode) {
1136  /* check if node2 is a leaf */
1137  if (!node2->totnode) {
1138  BVHTreeOverlap *overlap;
1139 
1140  if (UNLIKELY(node1 == node2)) {
1141  return;
1142  }
1143 
1144  /* both leafs, insert overlap! */
1145  overlap = BLI_stack_push_r(data_thread->overlap);
1146  overlap->indexA = node1->index;
1147  overlap->indexB = node2->index;
1148  }
1149  else {
1150  for (j = 0; j < data->tree2->tree_type; j++) {
1151  if (node2->children[j]) {
1152  tree_overlap_traverse(data_thread, node1, node2->children[j]);
1153  }
1154  }
1155  }
1156  }
1157  else {
1158  for (j = 0; j < data->tree1->tree_type; j++) {
1159  if (node1->children[j]) {
1160  tree_overlap_traverse(data_thread, node1->children[j], node2);
1161  }
1162  }
1163  }
1164  }
1165 }
1166 
1171  const BVHNode *node1,
1172  const BVHNode *node2)
1173 {
1174  BVHOverlapData_Shared *data = data_thread->shared;
1175  int j;
1176 
1177  if (tree_overlap_test(node1, node2, data->start_axis, data->stop_axis)) {
1178  /* check if node1 is a leaf */
1179  if (!node1->totnode) {
1180  /* check if node2 is a leaf */
1181  if (!node2->totnode) {
1182  BVHTreeOverlap *overlap;
1183 
1184  if (UNLIKELY(node1 == node2)) {
1185  return;
1186  }
1187 
1188  /* only difference to tree_overlap_traverse! */
1189  if (data->callback(data->userdata, node1->index, node2->index, data_thread->thread)) {
1190  /* both leafs, insert overlap! */
1191  overlap = BLI_stack_push_r(data_thread->overlap);
1192  overlap->indexA = node1->index;
1193  overlap->indexB = node2->index;
1194  }
1195  }
1196  else {
1197  for (j = 0; j < data->tree2->tree_type; j++) {
1198  if (node2->children[j]) {
1199  tree_overlap_traverse_cb(data_thread, node1, node2->children[j]);
1200  }
1201  }
1202  }
1203  }
1204  else {
1205  for (j = 0; j < data->tree1->tree_type; j++) {
1206  if (node1->children[j]) {
1207  tree_overlap_traverse_cb(data_thread, node1->children[j], node2);
1208  }
1209  }
1210  }
1211  }
1212 }
1213 
1218  const BVHNode *node1,
1219  const BVHNode *node2)
1220 {
1221  BVHOverlapData_Shared *data = data_thread->shared;
1222  int j;
1223 
1224  if (tree_overlap_test(node1, node2, data->start_axis, data->stop_axis)) {
1225  /* check if node1 is a leaf */
1226  if (!node1->totnode) {
1227  /* check if node2 is a leaf */
1228  if (!node2->totnode) {
1229  BVHTreeOverlap *overlap;
1230 
1231  if (UNLIKELY(node1 == node2)) {
1232  return false;
1233  }
1234 
1235  /* only difference to tree_overlap_traverse! */
1236  if (!data->callback ||
1237  data->callback(data->userdata, node1->index, node2->index, data_thread->thread)) {
1238  /* both leafs, insert overlap! */
1239  if (data_thread->overlap) {
1240  overlap = BLI_stack_push_r(data_thread->overlap);
1241  overlap->indexA = node1->index;
1242  overlap->indexB = node2->index;
1243  }
1244  return (--data_thread->max_interactions) == 0;
1245  }
1246  }
1247  else {
1248  for (j = 0; j < node2->totnode; j++) {
1249  if (tree_overlap_traverse_num(data_thread, node1, node2->children[j])) {
1250  return true;
1251  }
1252  }
1253  }
1254  }
1255  else {
1256  const uint max_interactions = data_thread->max_interactions;
1257  for (j = 0; j < node1->totnode; j++) {
1258  if (tree_overlap_traverse_num(data_thread, node1->children[j], node2)) {
1259  data_thread->max_interactions = max_interactions;
1260  }
1261  }
1262  }
1263  }
1264  return false;
1265 }
1266 
1273 {
1274  return (int)MIN2(tree->tree_type, tree->nodes[tree->totleaf]->totnode);
1275 }
1276 
1277 static void bvhtree_overlap_task_cb(void *__restrict userdata,
1278  const int j,
1279  const TaskParallelTLS *__restrict UNUSED(tls))
1280 {
1281  BVHOverlapData_Thread *data = &((BVHOverlapData_Thread *)userdata)[j];
1282  BVHOverlapData_Shared *data_shared = data->shared;
1283 
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]);
1288  }
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]);
1293  }
1294  else {
1296  data_shared->tree1->nodes[data_shared->tree1->totleaf]->children[j],
1297  data_shared->tree2->nodes[data_shared->tree2->totleaf]);
1298  }
1299 }
1300 
1302  const BVHTree *tree1,
1303  const BVHTree *tree2,
1304  uint *r_overlap_tot,
1305  /* optional callback to test the overlap before adding (must be thread-safe!) */
1307  void *userdata,
1308  const uint max_interactions,
1309  const int flag)
1310 {
1311  bool overlap_pairs = (flag & BVH_OVERLAP_RETURN_PAIRS) != 0;
1312  bool use_threading = (flag & BVH_OVERLAP_USE_THREADING) != 0 &&
1314 
1315  /* 'RETURN_PAIRS' was not implemented without 'max_interactions'. */
1316  BLI_assert(overlap_pairs || max_interactions);
1317 
1318  const int root_node_len = BLI_bvhtree_overlap_thread_num(tree1);
1319  const int thread_num = use_threading ? root_node_len : 1;
1320  int j;
1321  size_t total = 0;
1322  BVHTreeOverlap *overlap = NULL, *to = NULL;
1323  BVHOverlapData_Shared data_shared;
1324  BVHOverlapData_Thread *data = BLI_array_alloca(data, (size_t)thread_num);
1325  axis_t start_axis, stop_axis;
1326 
1327  /* check for compatibility of both trees (can't compare 14-DOP with 18-DOP) */
1328  if (UNLIKELY((tree1->axis != tree2->axis) && (tree1->axis == 14 || tree2->axis == 14) &&
1329  (tree1->axis == 18 || tree2->axis == 18))) {
1330  BLI_assert(0);
1331  return NULL;
1332  }
1333 
1334  const BVHNode *root1 = tree1->nodes[tree1->totleaf];
1335  const BVHNode *root2 = tree2->nodes[tree2->totleaf];
1336 
1337  start_axis = min_axis(tree1->start_axis, tree2->start_axis);
1338  stop_axis = min_axis(tree1->stop_axis, tree2->stop_axis);
1339 
1340  /* fast check root nodes for collision before doing big splitting + traversal */
1341  if (!tree_overlap_test(root1, root2, start_axis, stop_axis)) {
1342  return NULL;
1343  }
1344 
1345  data_shared.tree1 = tree1;
1346  data_shared.tree2 = tree2;
1347  data_shared.start_axis = start_axis;
1348  data_shared.stop_axis = stop_axis;
1349 
1350  /* can be NULL */
1351  data_shared.callback = callback;
1352  data_shared.userdata = userdata;
1353 
1354  for (j = 0; j < thread_num; j++) {
1355  /* init BVHOverlapData_Thread */
1356  data[j].shared = &data_shared;
1357  data[j].overlap = overlap_pairs ? BLI_stack_new(sizeof(BVHTreeOverlap), __func__) : NULL;
1358  data[j].max_interactions = max_interactions;
1359 
1360  /* for callback */
1361  data[j].thread = j;
1362  }
1363 
1364  if (use_threading) {
1365  TaskParallelSettings settings;
1367  settings.min_iter_per_thread = 1;
1368  BLI_task_parallel_range(0, root_node_len, data, bvhtree_overlap_task_cb, &settings);
1369  }
1370  else {
1371  if (max_interactions) {
1372  tree_overlap_traverse_num(data, root1, root2);
1373  }
1374  else if (callback) {
1375  tree_overlap_traverse_cb(data, root1, root2);
1376  }
1377  else {
1378  tree_overlap_traverse(data, root1, root2);
1379  }
1380  }
1381 
1382  if (overlap_pairs) {
1383  for (j = 0; j < thread_num; j++) {
1384  total += BLI_stack_count(data[j].overlap);
1385  }
1386 
1387  to = overlap = MEM_mallocN(sizeof(BVHTreeOverlap) * total, "BVHTreeOverlap");
1388 
1389  for (j = 0; j < thread_num; j++) {
1390  uint count = (uint)BLI_stack_count(data[j].overlap);
1391  BLI_stack_pop_n(data[j].overlap, to, count);
1392  BLI_stack_free(data[j].overlap);
1393  to += count;
1394  }
1395  *r_overlap_tot = (uint)total;
1396  }
1397 
1398  return overlap;
1399 }
1400 
1402  const BVHTree *tree1,
1403  const BVHTree *tree2,
1404  uint *r_overlap_tot,
1405  /* optional callback to test the overlap before adding (must be thread-safe!) */
1407  void *userdata)
1408 {
1409  return BLI_bvhtree_overlap_ex(tree1,
1410  tree2,
1411  r_overlap_tot,
1412  callback,
1413  userdata,
1414  0,
1416 }
1417 
1420 /* -------------------------------------------------------------------- */
1424 static bool tree_intersect_plane_test(const float *bv, const float plane[4])
1425 {
1426  /* TODO(germano): Support other kdop geometries. */
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];
1430  aabb_get_near_far_from_plane(plane, bb_min, bb_max, bb_near, bb_far);
1431  if ((plane_point_side_v3(plane, bb_near) > 0.0f) !=
1432  (plane_point_side_v3(plane, bb_far) > 0.0f)) {
1433  return true;
1434  }
1435 
1436  return false;
1437 }
1438 
1440  const BVHNode *node)
1441 {
1442  if (tree_intersect_plane_test(node->bv, data->plane)) {
1443  /* check if node is a leaf */
1444  if (!node->totnode) {
1445  int *intersect = BLI_stack_push_r(data->intersect);
1446  *intersect = node->index;
1447  }
1448  else {
1449  for (int j = 0; j < data->tree->tree_type; j++) {
1450  if (node->children[j]) {
1452  }
1453  }
1454  }
1455  }
1456 }
1457 
1458 int *BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_tot)
1459 {
1460  int *intersect = NULL;
1461  size_t total = 0;
1462 
1463  if (tree->totleaf) {
1465  data.tree = tree;
1466  copy_v4_v4(data.plane, plane);
1467  data.intersect = BLI_stack_new(sizeof(int), __func__);
1468 
1469  BVHNode *root = tree->nodes[tree->totleaf];
1471 
1472  total = BLI_stack_count(data.intersect);
1473  if (total) {
1474  intersect = MEM_mallocN(sizeof(int) * total, __func__);
1475  BLI_stack_pop_n(data.intersect, intersect, (uint)total);
1476  }
1477  BLI_stack_free(data.intersect);
1478  }
1479  *r_intersect_tot = (uint)total;
1480  return intersect;
1481 }
1482 
1485 /* -------------------------------------------------------------------- */
1489 /* Determines the nearest point of the given node BV.
1490  * Returns the squared distance to that point. */
1491 static float calc_nearest_point_squared(const float proj[3], BVHNode *node, float nearest[3])
1492 {
1493  int i;
1494  const float *bv = node->bv;
1495 
1496  /* nearest on AABB hull */
1497  for (i = 0; i != 3; i++, bv += 2) {
1498  float val = proj[i];
1499  if (bv[0] > val) {
1500  val = bv[0];
1501  }
1502  if (bv[1] < val) {
1503  val = bv[1];
1504  }
1505  nearest[i] = val;
1506  }
1507 
1508  return len_squared_v3v3(proj, nearest);
1509 }
1510 
1511 /* Depth first search method */
1513 {
1514  if (node->totnode == 0) {
1515  if (data->callback) {
1516  data->callback(data->userdata, node->index, data->co, &data->nearest);
1517  }
1518  else {
1519  data->nearest.index = node->index;
1520  data->nearest.dist_sq = calc_nearest_point_squared(data->proj, node, data->nearest.co);
1521  }
1522  }
1523  else {
1524  /* Better heuristic to pick the closest node to dive on */
1525  int i;
1526  float nearest[3];
1527 
1528  if (data->proj[node->main_axis] <= node->children[0]->bv[node->main_axis * 2 + 1]) {
1529 
1530  for (i = 0; i != node->totnode; i++) {
1531  if (calc_nearest_point_squared(data->proj, node->children[i], nearest) >=
1532  data->nearest.dist_sq) {
1533  continue;
1534  }
1535  dfs_find_nearest_dfs(data, node->children[i]);
1536  }
1537  }
1538  else {
1539  for (i = node->totnode - 1; i >= 0; i--) {
1540  if (calc_nearest_point_squared(data->proj, node->children[i], nearest) >=
1541  data->nearest.dist_sq) {
1542  continue;
1543  }
1544  dfs_find_nearest_dfs(data, node->children[i]);
1545  }
1546  }
1547  }
1548 }
1549 
1551 {
1552  float nearest[3], dist_sq;
1553  dist_sq = calc_nearest_point_squared(data->proj, node, nearest);
1554  if (dist_sq >= data->nearest.dist_sq) {
1555  return;
1556  }
1558 }
1559 
1560 /* Priority queue method */
1562 {
1563  if (node->totnode == 0) {
1564  if (data->callback) {
1565  data->callback(data->userdata, node->index, data->co, &data->nearest);
1566  }
1567  else {
1568  data->nearest.index = node->index;
1569  data->nearest.dist_sq = calc_nearest_point_squared(data->proj, node, data->nearest.co);
1570  }
1571  }
1572  else {
1573  float nearest[3];
1574 
1575  for (int i = 0; i != node->totnode; i++) {
1576  float dist_sq = calc_nearest_point_squared(data->proj, node->children[i], nearest);
1577 
1578  if (dist_sq < data->nearest.dist_sq) {
1579  BLI_heapsimple_insert(heap, dist_sq, node->children[i]);
1580  }
1581  }
1582  }
1583 }
1584 
1586 {
1587  float nearest[3];
1588  float dist_sq = calc_nearest_point_squared(data->proj, root, nearest);
1589 
1590  if (dist_sq < data->nearest.dist_sq) {
1591  HeapSimple *heap = BLI_heapsimple_new_ex(32);
1592 
1593  heap_find_nearest_inner(data, heap, root);
1594 
1595  while (!BLI_heapsimple_is_empty(heap) &&
1596  BLI_heapsimple_top_value(heap) < data->nearest.dist_sq) {
1599  }
1600 
1601  BLI_heapsimple_free(heap, NULL);
1602  }
1603 }
1604 
1606  const float co[3],
1607  BVHTreeNearest *nearest,
1609  void *userdata,
1610  int flag)
1611 {
1612  axis_t axis_iter;
1613 
1615  BVHNode *root = tree->nodes[tree->totleaf];
1616 
1617  /* init data to search */
1618  data.tree = tree;
1619  data.co = co;
1620 
1621  data.callback = callback;
1622  data.userdata = userdata;
1623 
1624  for (axis_iter = data.tree->start_axis; axis_iter != data.tree->stop_axis; axis_iter++) {
1625  data.proj[axis_iter] = dot_v3v3(data.co, bvhtree_kdop_axes[axis_iter]);
1626  }
1627 
1628  if (nearest) {
1629  memcpy(&data.nearest, nearest, sizeof(*nearest));
1630  }
1631  else {
1632  data.nearest.index = -1;
1633  data.nearest.dist_sq = FLT_MAX;
1634  }
1635 
1636  /* dfs search */
1637  if (root) {
1638  if (flag & BVH_NEAREST_OPTIMAL_ORDER) {
1639  heap_find_nearest_begin(&data, root);
1640  }
1641  else {
1642  dfs_find_nearest_begin(&data, root);
1643  }
1644  }
1645 
1646  /* copy back results */
1647  if (nearest) {
1648  memcpy(nearest, &data.nearest, sizeof(*nearest));
1649  }
1650 
1651  return data.nearest.index;
1652 }
1653 
1655  const float co[3],
1656  BVHTreeNearest *nearest,
1658  void *userdata)
1659 {
1660  return BLI_bvhtree_find_nearest_ex(tree, co, nearest, callback, userdata, 0);
1661 }
1662 
1665 /* -------------------------------------------------------------------- */
1669 static bool isect_aabb_v3(BVHNode *node, const float co[3])
1670 {
1671  const BVHTreeAxisRange *bv = (const BVHTreeAxisRange *)node->bv;
1672 
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) {
1675  return true;
1676  }
1677 
1678  return false;
1679 }
1680 
1682 {
1683  if (node->totnode == 0) {
1684  if (isect_aabb_v3(node, data->co)) {
1685  if (data->callback) {
1686  const float dist_sq = data->nearest.dist_sq;
1687  data->callback(data->userdata, node->index, data->co, &data->nearest);
1688  return (data->nearest.dist_sq < dist_sq);
1689  }
1690  data->nearest.index = node->index;
1691  return true;
1692  }
1693  }
1694  else {
1695  /* Better heuristic to pick the closest node to dive on */
1696  int i;
1697 
1698  if (data->proj[node->main_axis] <= node->children[0]->bv[node->main_axis * 2 + 1]) {
1699  for (i = 0; i != node->totnode; i++) {
1700  if (isect_aabb_v3(node->children[i], data->co)) {
1701  if (dfs_find_duplicate_fast_dfs(data, node->children[i])) {
1702  return true;
1703  }
1704  }
1705  }
1706  }
1707  else {
1708  for (i = node->totnode; i--;) {
1709  if (isect_aabb_v3(node->children[i], data->co)) {
1710  if (dfs_find_duplicate_fast_dfs(data, node->children[i])) {
1711  return true;
1712  }
1713  }
1714  }
1715  }
1716  }
1717  return false;
1718 }
1719 
1725  const float co[3],
1726  const float dist_sq,
1728  void *userdata)
1729 {
1731  BVHNode *root = tree->nodes[tree->totleaf];
1732 
1733  /* init data to search */
1734  data.tree = tree;
1735  data.co = co;
1736 
1737  data.callback = callback;
1738  data.userdata = userdata;
1739  data.nearest.index = -1;
1740  data.nearest.dist_sq = dist_sq;
1741 
1742  /* dfs search */
1743  if (root) {
1745  }
1746 
1747  return data.nearest.index;
1748 }
1749 
1752 /* -------------------------------------------------------------------- */
1759 /* Determines the distance that the ray must travel to hit the bounding volume of the given node */
1760 static float ray_nearest_hit(const BVHRayCastData *data, const float bv[6])
1761 {
1762  int i;
1763 
1764  float low = 0, upper = data->hit.dist;
1765 
1766  for (i = 0; i != 3; i++, bv += 2) {
1767  if (data->ray_dot_axis[i] == 0.0f) {
1768  /* axis aligned ray */
1769  if (data->ray.origin[i] < bv[0] - data->ray.radius ||
1770  data->ray.origin[i] > bv[1] + data->ray.radius) {
1771  return FLT_MAX;
1772  }
1773  }
1774  else {
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];
1777 
1778  if (data->ray_dot_axis[i] > 0.0f) {
1779  if (ll > low) {
1780  low = ll;
1781  }
1782  if (lu < upper) {
1783  upper = lu;
1784  }
1785  }
1786  else {
1787  if (lu > low) {
1788  low = lu;
1789  }
1790  if (ll < upper) {
1791  upper = ll;
1792  }
1793  }
1794 
1795  if (low > upper) {
1796  return FLT_MAX;
1797  }
1798  }
1799  }
1800  return low;
1801 }
1802 
1810 {
1811  const float *bv = node->bv;
1812 
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];
1819 
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)) {
1823  return FLT_MAX;
1824  }
1825  return max_fff(t1x, t1y, t1z);
1826 }
1827 
1829 {
1830  int i;
1831 
1832  /* ray-bv is really fast.. and simple tests revealed its worth to test it
1833  * before calling the ray-primitive functions */
1834  /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
1835  float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) :
1836  ray_nearest_hit(data, node->bv);
1837  if (dist >= data->hit.dist) {
1838  return;
1839  }
1840 
1841  if (node->totnode == 0) {
1842  if (data->callback) {
1843  data->callback(data->userdata, node->index, &data->ray, &data->hit);
1844  }
1845  else {
1846  data->hit.index = node->index;
1847  data->hit.dist = dist;
1848  madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist);
1849  }
1850  }
1851  else {
1852  /* pick loop direction to dive into the tree (based on ray direction and split axis) */
1853  if (data->ray_dot_axis[node->main_axis] > 0.0f) {
1854  for (i = 0; i != node->totnode; i++) {
1855  dfs_raycast(data, node->children[i]);
1856  }
1857  }
1858  else {
1859  for (i = node->totnode - 1; i >= 0; i--) {
1860  dfs_raycast(data, node->children[i]);
1861  }
1862  }
1863  }
1864 }
1865 
1870 {
1871  int i;
1872 
1873  /* ray-bv is really fast.. and simple tests revealed its worth to test it
1874  * before calling the ray-primitive functions */
1875  /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
1876  float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) :
1877  ray_nearest_hit(data, node->bv);
1878  if (dist >= data->hit.dist) {
1879  return;
1880  }
1881 
1882  if (node->totnode == 0) {
1883  /* no need to check for 'data->callback' (using 'all' only makes sense with a callback). */
1884  dist = data->hit.dist;
1885  data->callback(data->userdata, node->index, &data->ray, &data->hit);
1886  data->hit.index = -1;
1887  data->hit.dist = dist;
1888  }
1889  else {
1890  /* pick loop direction to dive into the tree (based on ray direction and split axis) */
1891  if (data->ray_dot_axis[node->main_axis] > 0.0f) {
1892  for (i = 0; i != node->totnode; i++) {
1893  dfs_raycast_all(data, node->children[i]);
1894  }
1895  }
1896  else {
1897  for (i = node->totnode - 1; i >= 0; i--) {
1898  dfs_raycast_all(data, node->children[i]);
1899  }
1900  }
1901  }
1902 }
1903 
1905 {
1906  int i;
1907 
1908  for (i = 0; i < 3; i++) {
1909  data->ray_dot_axis[i] = dot_v3v3(data->ray.direction, bvhtree_kdop_axes[i]);
1910 
1911  if (fabsf(data->ray_dot_axis[i]) < FLT_EPSILON) {
1912  data->ray_dot_axis[i] = 0.0f;
1913  /* Sign is not important in this case, `data->index` is adjusted anyway. */
1914  data->idot_axis[i] = FLT_MAX;
1915  }
1916  else {
1917  data->idot_axis[i] = 1.0f / data->ray_dot_axis[i];
1918  }
1919 
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;
1924  }
1925 
1926 #ifdef USE_KDOPBVH_WATERTIGHT
1927  if (flag & BVH_RAYCAST_WATERTIGHT) {
1928  isect_ray_tri_watertight_v3_precalc(&data->isect_precalc, data->ray.direction);
1929  data->ray.isect_precalc = &data->isect_precalc;
1930  }
1931  else {
1932  data->ray.isect_precalc = NULL;
1933  }
1934 #else
1935  UNUSED_VARS(flag);
1936 #endif
1937 }
1938 
1940  const float co[3],
1941  const float dir[3],
1942  float radius,
1943  BVHTreeRayHit *hit,
1945  void *userdata,
1946  int flag)
1947 {
1949  BVHNode *root = tree->nodes[tree->totleaf];
1950 
1951  BLI_ASSERT_UNIT_V3(dir);
1952 
1953  data.tree = tree;
1954 
1955  data.callback = callback;
1956  data.userdata = userdata;
1957 
1958  copy_v3_v3(data.ray.origin, co);
1959  copy_v3_v3(data.ray.direction, dir);
1960  data.ray.radius = radius;
1961 
1963 
1964  if (hit) {
1965  memcpy(&data.hit, hit, sizeof(*hit));
1966  }
1967  else {
1968  data.hit.index = -1;
1969  data.hit.dist = BVH_RAYCAST_DIST_MAX;
1970  }
1971 
1972  if (root) {
1973  dfs_raycast(&data, root);
1974  // iterative_raycast(&data, root);
1975  }
1976 
1977  if (hit) {
1978  memcpy(hit, &data.hit, sizeof(*hit));
1979  }
1980 
1981  return data.hit.index;
1982 }
1983 
1985  const float co[3],
1986  const float dir[3],
1987  float radius,
1988  BVHTreeRayHit *hit,
1990  void *userdata)
1991 {
1992  return BLI_bvhtree_ray_cast_ex(
1993  tree, co, dir, radius, hit, callback, userdata, BVH_RAYCAST_DEFAULT);
1994 }
1995 
1996 float BLI_bvhtree_bb_raycast(const float bv[6],
1997  const float light_start[3],
1998  const float light_end[3],
1999  float pos[3])
2000 {
2002  float dist;
2003 
2004  data.hit.dist = BVH_RAYCAST_DIST_MAX;
2005 
2006  /* get light direction */
2007  sub_v3_v3v3(data.ray.direction, light_end, light_start);
2008 
2009  data.ray.radius = 0.0;
2010 
2011  copy_v3_v3(data.ray.origin, light_start);
2012 
2013  normalize_v3(data.ray.direction);
2014  copy_v3_v3(data.ray_dot_axis, data.ray.direction);
2015 
2016  dist = ray_nearest_hit(&data, bv);
2017 
2018  madd_v3_v3v3fl(pos, light_start, data.ray.direction, dist);
2019 
2020  return dist;
2021 }
2022 
2033  const float co[3],
2034  const float dir[3],
2035  float radius,
2036  float hit_dist,
2038  void *userdata,
2039  int flag)
2040 {
2042  BVHNode *root = tree->nodes[tree->totleaf];
2043 
2044  BLI_ASSERT_UNIT_V3(dir);
2045  BLI_assert(callback != NULL);
2046 
2047  data.tree = tree;
2048 
2049  data.callback = callback;
2050  data.userdata = userdata;
2051 
2052  copy_v3_v3(data.ray.origin, co);
2053  copy_v3_v3(data.ray.direction, dir);
2054  data.ray.radius = radius;
2055 
2057 
2058  data.hit.index = -1;
2059  data.hit.dist = hit_dist;
2060 
2061  if (root) {
2062  dfs_raycast_all(&data, root);
2063  }
2064 }
2065 
2067  const float co[3],
2068  const float dir[3],
2069  float radius,
2070  float hit_dist,
2072  void *userdata)
2073 {
2075  tree, co, dir, radius, hit_dist, callback, userdata, BVH_RAYCAST_DEFAULT);
2076 }
2077 
2080 /* -------------------------------------------------------------------- */
2089 typedef struct RangeQueryData {
2091  const float *center;
2092  float radius_sq; /* squared radius */
2093 
2094  int hits;
2095 
2097  void *userdata;
2099 
2101 {
2102  if (node->totnode == 0) {
2103 #if 0 /*UNUSED*/
2104  /* Calculate the node min-coords
2105  * (if the node was a point then this is the point coordinates) */
2106  float co[3];
2107  co[0] = node->bv[0];
2108  co[1] = node->bv[2];
2109  co[2] = node->bv[4];
2110 #endif
2111  }
2112  else {
2113  int i;
2114  for (i = 0; i != node->totnode; i++) {
2115  float nearest[3];
2116  float dist_sq = calc_nearest_point_squared(data->center, node->children[i], nearest);
2117  if (dist_sq < data->radius_sq) {
2118  /* Its a leaf.. call the callback */
2119  if (node->children[i]->totnode == 0) {
2120  data->hits++;
2121  data->callback(data->userdata, node->children[i]->index, data->center, dist_sq);
2122  }
2123  else {
2124  dfs_range_query(data, node->children[i]);
2125  }
2126  }
2127  }
2128  }
2129 }
2130 
2132  BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata)
2133 {
2134  BVHNode *root = tree->nodes[tree->totleaf];
2135 
2137  data.tree = tree;
2138  data.center = co;
2139  data.radius_sq = radius * radius;
2140  data.hits = 0;
2141 
2142  data.callback = callback;
2143  data.userdata = userdata;
2144 
2145  if (root != NULL) {
2146  float nearest[3];
2147  float dist_sq = calc_nearest_point_squared(data.center, root, nearest);
2148  if (dist_sq < data.radius_sq) {
2149  /* Its a leaf.. call the callback */
2150  if (root->totnode == 0) {
2151  data.hits++;
2152  data.callback(data.userdata, root->index, co, dist_sq);
2153  }
2154  else {
2155  dfs_range_query(&data, root);
2156  }
2157  }
2158  }
2159 
2160  return data.hits;
2161 }
2162 
2165 /* -------------------------------------------------------------------- */
2170  const BVHNode *node)
2171 {
2172  if (node->totnode == 0) {
2173  if (data->callback) {
2174  data->callback(data->userdata, node->index, &data->precalc, NULL, 0, &data->nearest);
2175  }
2176  else {
2177  data->nearest.index = node->index;
2178  data->nearest.dist_sq = dist_squared_to_projected_aabb(
2179  &data->precalc,
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);
2183  }
2184  }
2185  else {
2186  /* First pick the closest node to recurse into */
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;
2190 
2191  if (dist_squared_to_projected_aabb(&data->precalc,
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) {
2196  }
2197  }
2198  }
2199  else {
2200  for (int i = node->totnode; i--;) {
2201  const float *bv = node->children[i]->bv;
2202 
2203  if (dist_squared_to_projected_aabb(&data->precalc,
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) {
2208  }
2209  }
2210  }
2211  }
2212 }
2213 
2215  BVHNearestProjectedData *__restrict data, const BVHNode *node)
2216 {
2217  if (node->totnode == 0) {
2218  if (data->callback) {
2219  data->callback(data->userdata,
2220  node->index,
2221  &data->precalc,
2222  data->clip_plane,
2223  data->clip_plane_len,
2224  &data->nearest);
2225  }
2226  else {
2227  data->nearest.index = node->index;
2228  data->nearest.dist_sq = dist_squared_to_projected_aabb(
2229  &data->precalc,
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);
2233  }
2234  }
2235  else {
2236  /* First pick the closest node to recurse into */
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]};
2242 
2243  int isect_type = isect_aabb_planes_v3(
2244  data->clip_plane, data->clip_plane_len, bb_min, bb_max);
2245 
2246  if ((isect_type != ISECT_AABB_PLANE_BEHIND_ANY) &&
2247  dist_squared_to_projected_aabb(&data->precalc, bb_min, bb_max, data->closest_axis) <=
2248  data->nearest.dist_sq) {
2249  if (isect_type == ISECT_AABB_PLANE_CROSS_ANY) {
2251  }
2252  else {
2253  /* ISECT_AABB_PLANE_IN_FRONT_ALL */
2255  }
2256  }
2257  }
2258  }
2259  else {
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]};
2264 
2265  int isect_type = isect_aabb_planes_v3(
2266  data->clip_plane, data->clip_plane_len, bb_min, bb_max);
2267 
2268  if (isect_type != ISECT_AABB_PLANE_BEHIND_ANY &&
2269  dist_squared_to_projected_aabb(&data->precalc, bb_min, bb_max, data->closest_axis) <=
2270  data->nearest.dist_sq) {
2271  if (isect_type == ISECT_AABB_PLANE_CROSS_ANY) {
2273  }
2274  else {
2275  /* ISECT_AABB_PLANE_IN_FRONT_ALL */
2277  }
2278  }
2279  }
2280  }
2281  }
2282 }
2283 
2285  float projmat[4][4],
2286  float winsize[2],
2287  float mval[2],
2288  float clip_plane[6][4],
2289  int clip_plane_len,
2290  BVHTreeNearest *nearest,
2292  void *userdata)
2293 {
2294  BVHNode *root = tree->nodes[tree->totleaf];
2295  if (root != NULL) {
2297  dist_squared_to_projected_aabb_precalc(&data.precalc, projmat, winsize, mval);
2298 
2299  data.callback = callback;
2300  data.userdata = userdata;
2301 
2302  if (clip_plane) {
2303  data.clip_plane_len = clip_plane_len;
2304  for (int i = 0; i < data.clip_plane_len; i++) {
2305  copy_v4_v4(data.clip_plane[i], clip_plane[i]);
2306  }
2307  }
2308  else {
2309  data.clip_plane_len = 1;
2310  planes_from_projmat(projmat, NULL, NULL, NULL, NULL, data.clip_plane[0], NULL);
2311  }
2312 
2313  if (nearest) {
2314  memcpy(&data.nearest, nearest, sizeof(*nearest));
2315  }
2316  else {
2317  data.nearest.index = -1;
2318  data.nearest.dist_sq = FLT_MAX;
2319  }
2320  {
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]};
2323 
2324  int isect_type = isect_aabb_planes_v3(data.clip_plane, data.clip_plane_len, bb_min, bb_max);
2325 
2326  if (isect_type != 0 &&
2327  dist_squared_to_projected_aabb(&data.precalc, bb_min, bb_max, data.closest_axis) <=
2328  data.nearest.dist_sq) {
2329  if (isect_type == 1) {
2331  }
2332  else {
2334  }
2335  }
2336  }
2337 
2338  if (nearest) {
2339  memcpy(nearest, &data.nearest, sizeof(*nearest));
2340  }
2341 
2342  return data.nearest.index;
2343  }
2344  return -1;
2345 }
2346 
2349 /* -------------------------------------------------------------------- */
2353 typedef struct BVHTree_WalkData {
2357  void *userdata;
2359 
2367 {
2368  if (node->totnode == 0) {
2369  return walk_data->walk_leaf_cb(
2370  (const BVHTreeAxisRange *)node->bv, node->index, walk_data->userdata);
2371  }
2372 
2373  /* First pick the closest node to recurse into */
2374  if (walk_data->walk_order_cb(
2375  (const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) {
2376  for (int i = 0; i != node->totnode; i++) {
2377  if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
2378  walk_data->userdata)) {
2379  if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
2380  return false;
2381  }
2382  }
2383  }
2384  }
2385  else {
2386  for (int i = node->totnode - 1; i >= 0; i--) {
2387  if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
2388  walk_data->userdata)) {
2389  if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
2390  return false;
2391  }
2392  }
2393  }
2394  }
2395  return true;
2396 }
2397 
2411  BVHTree_WalkParentCallback walk_parent_cb,
2412  BVHTree_WalkLeafCallback walk_leaf_cb,
2413  BVHTree_WalkOrderCallback walk_order_cb,
2414  void *userdata)
2415 {
2416  const BVHNode *root = tree->nodes[tree->totleaf];
2417  if (root != NULL) {
2418  BVHTree_WalkData walk_data = {walk_parent_cb, walk_leaf_cb, walk_order_cb, userdata};
2419  /* first make sure the bv of root passes in the test too */
2420  if (walk_parent_cb((const BVHTreeAxisRange *)root->bv, userdata)) {
2421  bvhtree_walk_dfs_recursive(&walk_data, root);
2422  }
2423  }
2424 }
2425 
typedef float(TangentPoint)[2]
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:36
#define BLI_assert(a)
Definition: BLI_assert.h:58
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)
Definition: BLI_kdopbvh.c:790
int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata)
Definition: BLI_kdopbvh.c:2131
static void bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(BVHNearestProjectedData *__restrict data, const BVHNode *node)
Definition: BLI_kdopbvh.c:2214
static void dfs_raycast_all(BVHRayCastData *data, BVHNode *node)
Definition: BLI_kdopbvh.c:1869
unsigned char axis_t
Definition: BLI_kdopbvh.c:77
static void bvhtree_ray_cast_data_precalc(BVHRayCastData *data, int flag)
Definition: BLI_kdopbvh.c:1904
static void bvhtree_node_inflate(const BVHTree *tree, BVHNode *node, const float dist)
Definition: BLI_kdopbvh.c:988
int BLI_bvhtree_get_tree_type(const BVHTree *tree)
Definition: BLI_kdopbvh.c:1069
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)
Definition: BLI_kdopbvh.c:2284
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)
Definition: BLI_kdopbvh.c:2032
int BLI_bvhtree_find_nearest_first(BVHTree *tree, const float co[3], const float dist_sq, BVHTree_NearestPointCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1724
struct RangeQueryData RangeQueryData
struct BVHRayCastData BVHRayCastData
static void heap_find_nearest_begin(BVHNearestData *data, BVHNode *root)
Definition: BLI_kdopbvh.c:1585
static void bvh_insertionsort(BVHNode **a, int lo, int hi, int axis)
Definition: BLI_kdopbvh.c:261
#define KDOPBVH_THREAD_LEAF_THRESHOLD
Definition: BLI_kdopbvh.c:70
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)
Definition: BLI_kdopbvh.c:1301
static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNode *node)
Definition: BLI_kdopbvh.c:2366
int BLI_bvhtree_find_nearest_ex(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata, int flag)
Definition: BLI_kdopbvh.c:1605
static bool tree_intersect_plane_test(const float *bv, const float plane[4])
Definition: BLI_kdopbvh.c:1424
static void tree_overlap_traverse_cb(BVHOverlapData_Thread *data_thread, const BVHNode *node1, const BVHNode *node2)
Definition: BLI_kdopbvh.c:1170
static char get_largest_axis(const float *bv)
Definition: BLI_kdopbvh.c:420
const float bvhtree_kdop_axes[13][3]
Definition: BLI_kdopbvh.c:186
static void build_implicit_tree_helper(const BVHTree *tree, BVHBuildHelper *data)
Definition: BLI_kdopbvh.c:586
int * BLI_bvhtree_intersect_plane(BVHTree *tree, float plane[4], uint *r_intersect_tot)
Definition: BLI_kdopbvh.c:1458
static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node)
Definition: BLI_kdopbvh.c:1550
static bool tree_overlap_test(const BVHNode *node1, const BVHNode *node2, axis_t start_axis, axis_t stop_axis)
Definition: BLI_kdopbvh.c:1107
static bool tree_overlap_traverse_num(BVHOverlapData_Thread *data_thread, const BVHNode *node1, const BVHNode *node2)
Definition: BLI_kdopbvh.c:1217
void BLI_bvhtree_balance(BVHTree *tree)
Definition: BLI_kdopbvh.c:956
BVHTree * BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
Definition: BLI_kdopbvh.c:873
static void heap_find_nearest_inner(BVHNearestData *data, HeapSimple *heap, BVHNode *node)
Definition: BLI_kdopbvh.c:1561
void BLI_bvhtree_update_tree(BVHTree *tree)
Definition: BLI_kdopbvh.c:1044
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)
Definition: BLI_kdopbvh.c:1939
static bool isect_aabb_v3(BVHNode *node, const float co[3])
Definition: BLI_kdopbvh.c:1669
MINLINE axis_t min_axis(axis_t a, axis_t b)
Definition: BLI_kdopbvh.c:223
float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3])
Definition: BLI_kdopbvh.c:1996
static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
Definition: BLI_kdopbvh.c:1828
static float ray_nearest_hit(const BVHRayCastData *data, const float bv[6])
Definition: BLI_kdopbvh.c:1760
struct BVHOverlapData_Thread BVHOverlapData_Thread
struct BVHNearestData BVHNearestData
void BLI_bvhtree_free(BVHTree *tree)
Definition: BLI_kdopbvh.c:945
static void dfs_range_query(RangeQueryData *data, BVHNode *node)
Definition: BLI_kdopbvh.c:2100
static void refit_kdop_hull(const BVHTree *tree, BVHNode *node, int start, int end)
Definition: BLI_kdopbvh.c:390
static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *node)
Definition: BLI_kdopbvh.c:1809
static bool dfs_find_duplicate_fast_dfs(BVHNearestData *data, BVHNode *node)
Definition: BLI_kdopbvh.c:1681
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
Definition: BLI_kdopbvh.c:998
static int bvh_partition(BVHNode **a, int lo, int hi, BVHNode *x, int axis)
Definition: BLI_kdopbvh.c:276
static void node_join(BVHTree *tree, BVHNode *node)
Definition: BLI_kdopbvh.c:442
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)
Definition: BLI_kdopbvh.c:1017
static void tree_overlap_traverse(BVHOverlapData_Thread *data_thread, const BVHNode *node1, const BVHNode *node2)
Definition: BLI_kdopbvh.c:1126
void BLI_bvhtree_walk_dfs(BVHTree *tree, BVHTree_WalkParentCallback walk_parent_cb, BVHTree_WalkLeafCallback walk_leaf_cb, BVHTree_WalkOrderCallback walk_order_cb, void *userdata)
Definition: BLI_kdopbvh.c:2410
struct BVHDivNodesData BVHDivNodesData
static void non_recursive_bvh_div_nodes_task_cb(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: BLI_kdopbvh.c:706
static void node_minmax_init(const BVHTree *tree, BVHNode *node)
Definition: BLI_kdopbvh.c:241
int BLI_bvhtree_get_len(const BVHTree *tree)
Definition: BLI_kdopbvh.c:1061
static const float bvhtree_kdop_axes_length[13]
Definition: BLI_kdopbvh.c:203
int BLI_bvhtree_overlap_thread_num(const BVHTree *tree)
Definition: BLI_kdopbvh.c:1272
#define MAX_TREETYPE
Definition: BLI_kdopbvh.c:62
static void partition_nth_element(BVHNode **a, int begin, int end, const int n, const int axis)
Definition: BLI_kdopbvh.c:321
static void split_leafs(BVHNode **leafs_array, const int nth[], const int partitions, const int split_axis)
Definition: BLI_kdopbvh.c:676
float BLI_bvhtree_get_epsilon(const BVHTree *tree)
Definition: BLI_kdopbvh.c:1074
static void bvhtree_nearest_projected_dfs_recursive(BVHNearestProjectedData *__restrict data, const BVHNode *node)
Definition: BLI_kdopbvh.c:2169
BVHOverlapData_Shared
Definition: BLI_kdopbvh.c:118
static float calc_nearest_point_squared(const float proj[3], BVHNode *node, float nearest[3])
Definition: BLI_kdopbvh.c:1491
void BLI_bvhtree_get_bounding_box(BVHTree *tree, float r_bb_min[3], float r_bb_max[3])
Definition: BLI_kdopbvh.c:1082
BVHTreeOverlap * BLI_bvhtree_overlap(const BVHTree *tree1, const BVHTree *tree2, uint *r_overlap_tot, BVHTree_OverlapCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1401
struct BVHNode BVHNode
static int implicit_needed_branches(int tree_type, int leafs)
Definition: BLI_kdopbvh.c:659
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)
Definition: BLI_kdopbvh.c:2066
BLI_STATIC_ASSERT((sizeof(void *)==8 &&sizeof(BVHTree)<=48)||(sizeof(void *)==4 &&sizeof(BVHTree)<=32), "over sized")
Definition: BLI_kdopbvh.c:106
static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node)
Definition: BLI_kdopbvh.c:1512
int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1984
static void bvhtree_overlap_task_cb(void *__restrict userdata, const int j, const TaskParallelTLS *__restrict UNUSED(tls))
Definition: BLI_kdopbvh.c:1277
struct BVHBuildHelper BVHBuildHelper
static void create_kdop_hull(const BVHTree *tree, BVHNode *node, const float *co, int numpoints, int moving)
Definition: BLI_kdopbvh.c:360
static void bvhtree_intersect_plane_dfs_recursive(BVHIntersectPlaneData *__restrict data, const BVHNode *node)
Definition: BLI_kdopbvh.c:1439
static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, const int child_index)
Definition: BLI_kdopbvh.c:616
int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
Definition: BLI_kdopbvh.c:1654
static BVHNode * bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis)
Definition: BLI_kdopbvh.c:296
@ BVH_NEAREST_OPTIMAL_ORDER
Definition: BLI_kdopbvh.h:98
@ BVH_OVERLAP_USE_THREADING
Definition: BLI_kdopbvh.h:93
@ BVH_OVERLAP_RETURN_PAIRS
Definition: BLI_kdopbvh.h:94
#define BVH_RAYCAST_DIST_MAX
Definition: BLI_kdopbvh.h:105
#define BVH_RAYCAST_DEFAULT
Definition: BLI_kdopbvh.h:104
bool(* BVHTree_WalkLeafCallback)(const BVHTreeAxisRange *bounds, int index, void *userdata)
Definition: BLI_kdopbvh.h:137
bool(* BVHTree_WalkOrderCallback)(const BVHTreeAxisRange *bounds, char axis, void *userdata)
Definition: BLI_kdopbvh.h:141
void(* BVHTree_RayCastCallback)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit)
Definition: BLI_kdopbvh.h:114
@ BVH_RAYCAST_WATERTIGHT
Definition: BLI_kdopbvh.h:102
bool(* BVHTree_WalkParentCallback)(const BVHTreeAxisRange *bounds, void *userdata)
Definition: BLI_kdopbvh.h:135
void(* BVHTree_NearestProjectedCallback)(void *userdata, int index, const struct DistProjectedAABBPrecalc *precalc, const float(*clip_plane)[4], const int clip_plane_len, BVHTreeNearest *nearest)
Definition: BLI_kdopbvh.h:126
void(* BVHTree_NearestPointCallback)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest)
Definition: BLI_kdopbvh.h:108
bool(* BVHTree_OverlapCallback)(void *userdata, int index_a, int index_b, int thread)
Definition: BLI_kdopbvh.h:120
void(* BVHTree_RangeQuery)(void *userdata, int index, const float co[3], float dist_sq)
Definition: BLI_kdopbvh.h:123
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])
Definition: math_geom.c:1879
float dist_squared_to_projected_aabb(struct DistProjectedAABBPrecalc *data, const float bbmin[3], const float bbmax[3], bool r_axis_closest[3])
Definition: math_geom.c:875
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])
Definition: math_geom.c:823
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])
Definition: math_geom.c:660
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])
Definition: math_geom.c:4911
int isect_aabb_planes_v3(const float(*planes)[4], const int totplane, const float bbmin[3], const float bbmax[3])
Definition: math_geom.c:2766
#define MINLINE
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()
Definition: stack.c:127
void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n) ATTR_NONNULL()
Definition: stack.c:193
size_t BLI_stack_count(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: stack.c:285
void BLI_stack_free(BLI_Stack *stack) ATTR_NONNULL()
Definition: stack.c:114
#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...
unsigned int uint
Definition: BLI_sys_types.h:83
void BLI_task_parallel_range(const int start, const int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
Definition: task_range.cc:110
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
Definition: BLI_task.h:231
#define UNUSED_VARS(...)
#define SWAP(type, a, b)
#define UNUSED(x)
#define UNLIKELY(x)
#define MIN2(a, b)
_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.
#define MEM_SAFE_FREE(v)
OperationNode * node
DEGForeachIDComponentCallback callback
void * tree
uint pos
int count
#define fabsf(x)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
size_t(* MEM_allocN_len)(const void *vmemh)
Definition: mallocn.c:40
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
static int left
static unsigned a[3]
Definition: RandGen.cpp:92
static double epsilon
#define min(a, b)
Definition: sort.c:51
int leafs_per_child[32]
Definition: BLI_kdopbvh.c:577
int branches_on_level[32]
Definition: BLI_kdopbvh.c:579
BVHNode ** leafs_array
Definition: BLI_kdopbvh.c:694
const BVHTree * tree
Definition: BLI_kdopbvh.c:692
const BVHBuildHelper * data
Definition: BLI_kdopbvh.c:699
BVHNode * branches_array
Definition: BLI_kdopbvh.c:693
const BVHTree * tree
Definition: BLI_kdopbvh.c:171
struct BLI_Stack * intersect
Definition: BLI_kdopbvh.c:173
const BVHTree * tree
Definition: BLI_kdopbvh.c:129
const float * co
Definition: BLI_kdopbvh.c:130
float proj[13]
Definition: BLI_kdopbvh.c:133
BVHTreeNearest nearest
Definition: BLI_kdopbvh.c:134
BVHTree_NearestPointCallback callback
Definition: BLI_kdopbvh.c:131
const BVHTree * tree
Definition: BLI_kdopbvh.c:159
struct DistProjectedAABBPrecalc precalc
Definition: BLI_kdopbvh.c:160
BVHTree_NearestProjectedCallback callback
Definition: BLI_kdopbvh.c:164
BVHTreeNearest nearest
Definition: BLI_kdopbvh.c:166
struct BVHNode * parent
Definition: BLI_kdopbvh.c:81
char totnode
Definition: BLI_kdopbvh.c:87
struct BVHNode ** children
Definition: BLI_kdopbvh.c:80
char main_axis
Definition: BLI_kdopbvh.c:88
int index
Definition: BLI_kdopbvh.c:86
float * bv
Definition: BLI_kdopbvh.c:85
struct BLI_Stack * overlap
Definition: BLI_kdopbvh.c:122
BVHOverlapData_Shared * shared
Definition: BLI_kdopbvh.c:121
BVHTree_RayCastCallback callback
Definition: BLI_kdopbvh.c:141
const BVHTree * tree
Definition: BLI_kdopbvh.c:139
float idot_axis[13]
Definition: BLI_kdopbvh.c:152
BVHTreeRayHit hit
Definition: BLI_kdopbvh.c:155
float ray_dot_axis[13]
Definition: BLI_kdopbvh.c:151
BVHTreeRay ray
Definition: BLI_kdopbvh.c:144
BVHTree_WalkOrderCallback walk_order_cb
Definition: BLI_kdopbvh.c:2356
BVHTree_WalkLeafCallback walk_leaf_cb
Definition: BLI_kdopbvh.c:2355
BVHTree_WalkParentCallback walk_parent_cb
Definition: BLI_kdopbvh.c:2354
axis_t axis
Definition: BLI_kdopbvh.c:101
float * nodebv
Definition: BLI_kdopbvh.c:96
axis_t start_axis
Definition: BLI_kdopbvh.c:100
int totleaf
Definition: BLI_kdopbvh.c:98
BVHNode * nodearray
Definition: BLI_kdopbvh.c:94
float epsilon
Definition: BLI_kdopbvh.c:97
BVHNode ** nodechild
Definition: BLI_kdopbvh.c:95
BVHNode ** nodes
Definition: BLI_kdopbvh.c:93
int totbranch
Definition: BLI_kdopbvh.c:99
axis_t stop_axis
Definition: BLI_kdopbvh.c:100
char tree_type
Definition: BLI_kdopbvh.c:102
BVHTree_RangeQuery callback
Definition: BLI_kdopbvh.c:2096
const float * center
Definition: BLI_kdopbvh.c:2091
BVHTree * tree
Definition: BLI_kdopbvh.c:2090
float max
__forceinline ssef low(const avxf &a)
Definition: util_avxf.h:277
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)