50
44
#define MAX_TREETYPE 32
51
#define DEFAULT_FIND_NEAREST_HEAP_SIZE 1024
53
typedef struct BVHNode
46
typedef unsigned char axis_t;
48
typedef struct BVHNode {
55
49
struct BVHNode **children;
56
struct BVHNode *parent; // some user defined traversed need that
50
struct BVHNode *parent; /* some user defined traversed need that */
57
51
struct BVHNode *skip[2];
58
float *bv; // Bounding volume of all nodes, max 13 axis
59
int index; // face, edge, vertex index
60
char totnode; // how many nodes are used, used for speedup
61
char main_axis; // Axis used to split this node
52
float *bv; /* Bounding volume of all nodes, max 13 axis */
53
int index; /* face, edge, vertex index */
54
char totnode; /* how many nodes are used, used for speedup */
55
char main_axis; /* Axis used to split this node */
58
/* keep under 26 bytes for speed purposes */
67
BVHNode *nodearray; /* pre-alloc branch nodes */
68
BVHNode **nodechild; // pre-alloc childs for nodes
69
float *nodebv; // pre-alloc bounding-volumes for nodes
70
float epsilon; /* epslion is used for inflation of the k-dop */
73
char tree_type; // type of tree (4 => quadtree)
74
char axis; // kdop type (6 => OBB, 7 => AABB, ...)
75
char start_axis, stop_axis; // KDOP_AXES array indices according to axis
61
BVHNode *nodearray; /* pre-alloc branch nodes */
62
BVHNode **nodechild; /* pre-alloc childs for nodes */
63
float *nodebv; /* pre-alloc bounding-volumes for nodes */
64
float epsilon; /* epslion is used for inflation of the k-dop */
65
int totleaf; /* leafs */
67
axis_t start_axis, stop_axis; /* KDOP_AXES array indices according to axis */
68
axis_t axis; /* kdop type (6 => OBB, 7 => AABB, ...) */
69
char tree_type; /* type of tree (4 => quadtree) */
78
typedef struct BVHOverlapData
72
/* optimization, ensure we stay small */
73
BLI_STATIC_ASSERT((sizeof(void *) == 8 && sizeof(BVHTree) <= 48) ||
74
(sizeof(void *) == 4 && sizeof(BVHTree) <= 32),
77
typedef struct BVHOverlapData {
80
78
BVHTree *tree1, *tree2;
81
79
BVHTreeOverlap *overlap;
82
80
int i, max_overlap; /* i is number of overlaps */
83
int start_axis, stop_axis;
81
axis_t start_axis, stop_axis;
86
typedef struct BVHNearestData
84
typedef struct BVHNearestData {
90
87
BVHTree_NearestPointCallback callback;
92
float proj[13]; //coordinates projection over axis
89
float proj[13]; /* coordinates projection over axis */
93
90
BVHTreeNearest nearest;
97
typedef struct BVHRayCastData
94
typedef struct BVHRayCastData {
101
97
BVHTree_RayCastCallback callback;
106
102
float ray_dot_axis[13];
107
103
float idot_axis[13];
110
106
BVHTreeRayHit hit;
111
107
} BVHRayCastData;
112
////////////////////////////////////////m
115
////////////////////////////////////////////////////////////////////////
116
// Bounding Volume Hierarchy Definition
118
// Notes: From OBB until 26-DOP --> all bounding volumes possible, just choose type below
119
// Notes: You have to choose the type at compile time ITM
120
// Notes: You can choose the tree type --> binary, quad, octree, choose below
121
////////////////////////////////////////////////////////////////////////
123
static float KDOP_AXES[13][3] =
124
{ {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}, {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, -1.0},
125
{1.0, -1.0, -1.0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, -1.0, 0}, {1.0, 0, -1.0},
111
* Bounding Volume Hierarchy Definition
113
* Notes: From OBB until 26-DOP --> all bounding volumes possible, just choose type below
114
* Notes: You have to choose the type at compile time ITM
115
* Notes: You can choose the tree type --> binary, quad, octree, choose below
118
static float KDOP_AXES[13][3] = {
119
{1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}, {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, -1.0},
120
{1.0, -1.0, -1.0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, -1.0, 0}, {1.0, 0, -1.0},
124
MINLINE axis_t min_axis(axis_t a, axis_t b)
126
return (a < b) ? a : b;
128
MINLINE axis_t max_axis(axis_t a, axis_t b)
130
return (b < a) ? a : b;
130
136
* Generic push and pop heap
132
#define PUSH_HEAP_BODY(HEAP_TYPE,PRIORITY,heap,heap_size) \
134
HEAP_TYPE element = heap[heap_size-1]; \
135
int child = heap_size-1; \
138
int parent = (child-1) / 2; \
139
if (PRIORITY(element, heap[parent])) \
141
heap[child] = heap[parent]; \
146
heap[child] = element; \
149
#define POP_HEAP_BODY(HEAP_TYPE, PRIORITY,heap,heap_size) \
151
HEAP_TYPE element = heap[heap_size-1]; \
153
while (parent < (heap_size-1)/2 ) \
155
int child2 = (parent+1)*2; \
156
if (PRIORITY(heap[child2-1], heap[child2])) \
159
if (PRIORITY(element, heap[child2])) \
162
heap[parent] = heap[child2]; \
165
heap[parent] = element; \
138
#define PUSH_HEAP_BODY(HEAP_TYPE, PRIORITY, heap, heap_size) \
140
HEAP_TYPE element = heap[heap_size - 1]; \
141
int child = heap_size - 1; \
144
int parent = (child - 1) / 2; \
145
if (PRIORITY(element, heap[parent])) \
147
heap[child] = heap[parent]; \
152
heap[child] = element; \
155
#define POP_HEAP_BODY(HEAP_TYPE, PRIORITY, heap, heap_size) \
157
HEAP_TYPE element = heap[heap_size - 1]; \
159
while (parent < (heap_size - 1) / 2) \
161
int child2 = (parent + 1) * 2; \
162
if (PRIORITY(heap[child2 - 1], heap[child2])) { \
165
if (PRIORITY(element, heap[child2])) { \
168
heap[parent] = heap[child2]; \
171
heap[parent] = element; \
169
174
static int ADJUST_MEMORY(void *local_memblock, void **memblock, int new_size, int *max_size, int size_per_item)
171
int new_max_size = *max_size * 2;
176
int new_max_size = *max_size * 2;
172
177
void *new_memblock = NULL;
174
179
if (new_size <= *max_size)
252
256
static void bvh_downheap(BVHNode **a, int i, int n, int lo, int axis)
254
BVHNode * d = a[lo+i-1];
258
BVHNode *d = a[lo + i - 1];
259
if ((child < n) && ((a[lo+child-1])->bv[axis] < (a[lo+child])->bv[axis]))
263
if ((child < n) && ((a[lo + child - 1])->bv[axis] < (a[lo + child])->bv[axis]))
263
if (!(d->bv[axis] < (a[lo+child-1])->bv[axis])) break;
264
a[lo+i-1] = a[lo+child-1];
267
if (!(d->bv[axis] < (a[lo + child - 1])->bv[axis])) break;
268
a[lo + i - 1] = a[lo + child - 1];
270
274
static void bvh_heapsort(BVHNode **a, int lo, int hi, int axis)
273
for (i=n/2; i>=1; i=i-1)
277
for (i = n / 2; i >= 1; i = i - 1)
275
bvh_downheap(a, i,n,lo, axis);
279
bvh_downheap(a, i, n, lo, axis);
277
for (i=n; i>1; i=i-1)
281
for (i = n; i > 1; i = i - 1)
279
SWAP(BVHNode*, a[lo],a[lo+i-1]);
280
bvh_downheap(a, 1,i-1,lo, axis);
283
SWAP(BVHNode *, a[lo], a[lo + i - 1]);
284
bvh_downheap(a, 1, i - 1, lo, axis);
285
static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis) // returns Sortable
289
static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis) /* returns Sortable */
287
if ((a[mid])->bv[axis] < (a[lo])->bv[axis])
291
if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) {
289
292
if ((a[hi])->bv[axis] < (a[mid])->bv[axis])
293
295
if ((a[hi])->bv[axis] < (a[lo])->bv[axis])
301
if ((a[hi])->bv[axis] < (a[mid])->bv[axis])
302
if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
303
303
if ((a[hi])->bv[axis] < (a[lo])->bv[axis])
395
393
float *bv = node->bv;
398
// don't init boudings for the moving case
401
for (i = tree->start_axis; i < tree->stop_axis; i++)
404
bv[2*i + 1] = -FLT_MAX;
397
/* don't init boudings for the moving case */
399
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
400
bv[2 * axis_iter] = FLT_MAX;
401
bv[2 * axis_iter + 1] = -FLT_MAX;
408
for (k = 0; k < numpoints; k++)
411
for (i = tree->start_axis; i < tree->stop_axis; i++)
413
newminmax = dot_v3v3(&co[k * 3], KDOP_AXES[i]);
414
if (newminmax < bv[2 * i])
415
bv[2 * i] = newminmax;
416
if (newminmax > bv[(2 * i) + 1])
417
bv[(2 * i) + 1] = newminmax;
405
for (k = 0; k < numpoints; k++) {
407
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
408
newminmax = dot_v3v3(&co[k * 3], KDOP_AXES[axis_iter]);
409
if (newminmax < bv[2 * axis_iter])
410
bv[2 * axis_iter] = newminmax;
411
if (newminmax > bv[(2 * axis_iter) + 1])
412
bv[(2 * axis_iter) + 1] = newminmax;
422
// depends on the fact that the BVH's for each face is already build
417
/* depends on the fact that the BVH's for each face is already build */
423
418
static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end)
420
float newmin, newmax;
427
421
float *bv = node->bv;
430
for (i = tree->start_axis; i < tree->stop_axis; i++)
433
bv[2*i + 1] = -FLT_MAX;
425
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
426
bv[(2 * axis_iter)] = FLT_MAX;
427
bv[(2 * axis_iter) + 1] = -FLT_MAX;
436
for (j = start; j < end; j++)
439
for (i = tree->start_axis; i < tree->stop_axis; i++)
441
newmin = tree->nodes[j]->bv[(2 * i)];
442
if ((newmin < bv[(2 * i)]))
443
bv[(2 * i)] = newmin;
445
newmax = tree->nodes[j]->bv[(2 * i) + 1];
446
if ((newmax > bv[(2 * i) + 1]))
447
bv[(2 * i) + 1] = newmax;
430
for (j = start; j < end; j++) {
432
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
433
newmin = tree->nodes[j]->bv[(2 * axis_iter)];
434
if ((newmin < bv[(2 * axis_iter)]))
435
bv[(2 * axis_iter)] = newmin;
437
newmax = tree->nodes[j]->bv[(2 * axis_iter) + 1];
438
if ((newmax > bv[(2 * axis_iter) + 1]))
439
bv[(2 * axis_iter) + 1] = newmax;
453
// only supports x,y,z axis in the moment
454
// but we should use a plain and simple function here for speed sake
445
/* only supports x,y,z axis in the moment
446
* but we should use a plain and simple function here for speed sake */
455
447
static char get_largest_axis(float *bv)
457
449
float middle_point[3];
459
middle_point[0] = (bv[1]) - (bv[0]); // x axis
460
middle_point[1] = (bv[3]) - (bv[2]); // y axis
461
middle_point[2] = (bv[5]) - (bv[4]); // z axis
462
if (middle_point[0] > middle_point[1])
451
middle_point[0] = (bv[1]) - (bv[0]); /* x axis */
452
middle_point[1] = (bv[3]) - (bv[2]); /* y axis */
453
middle_point[2] = (bv[5]) - (bv[4]); /* z axis */
454
if (middle_point[0] > middle_point[1]) {
464
455
if (middle_point[0] > middle_point[2])
465
return 1; // max x axis
456
return 1; /* max x axis */
467
return 5; // max z axis
458
return 5; /* max z axis */
471
461
if (middle_point[1] > middle_point[2])
472
return 3; // max y axis
462
return 3; /* max y axis */
474
return 5; // max z axis
464
return 5; /* max z axis */
478
// bottom-up update of bvh node BV
479
// join the children on the parent BV
468
/* bottom-up update of bvh node BV
469
* join the children on the parent BV */
480
470
static void node_join(BVHTree *tree, BVHNode *node)
484
for (i = tree->start_axis; i < tree->stop_axis; i++)
486
node->bv[2*i] = FLT_MAX;
487
node->bv[2*i + 1] = -FLT_MAX;
475
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
476
node->bv[(2 * axis_iter)] = FLT_MAX;
477
node->bv[(2 * axis_iter) + 1] = -FLT_MAX;
490
for (i = 0; i < tree->tree_type; i++)
492
if (node->children[i])
494
for (j = tree->start_axis; j < tree->stop_axis; j++)
497
if (node->children[i]->bv[(2 * j)] < node->bv[(2 * j)])
498
node->bv[(2 * j)] = node->children[i]->bv[(2 * j)];
501
if (node->children[i]->bv[(2 * j) + 1] > node->bv[(2 * j) + 1])
502
node->bv[(2 * j) + 1] = node->children[i]->bv[(2 * j) + 1];
480
for (i = 0; i < tree->tree_type; i++) {
481
if (node->children[i]) {
482
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
484
if (node->children[i]->bv[(2 * axis_iter)] < node->bv[(2 * axis_iter)])
485
node->bv[(2 * axis_iter)] = node->children[i]->bv[(2 * axis_iter)];
488
if (node->children[i]->bv[(2 * axis_iter) + 1] > node->bv[(2 * axis_iter) + 1])
489
node->bv[(2 * axis_iter) + 1] = node->children[i]->bv[(2 * axis_iter) + 1];
756
branches_array--; //Implicit trees use 1-based indexs
741
branches_array--; /* Implicit trees use 1-based indexs */
758
743
build_implicit_tree_helper(tree, &data);
760
//Loop tree levels (log N) loops
761
for (i=1, depth = 1; i <= num_branches; i = i*tree_type + tree_offset, depth++)
763
const int first_of_next_level = i*tree_type + tree_offset;
764
const int end_j = MIN2(first_of_next_level, num_branches + 1); //index of last branch on this level
745
/* Loop tree levels (log N) loops */
746
for (i = 1, depth = 1; i <= num_branches; i = i * tree_type + tree_offset, depth++) {
747
const int first_of_next_level = i * tree_type + tree_offset;
748
const int end_j = min_ii(first_of_next_level, num_branches + 1); /* index of last branch on this level */
767
//Loop all branches on this level
751
/* Loop all branches on this level */
768
752
#pragma omp parallel for private(j) schedule(static)
769
753
for (j = i; j < end_j; j++) {
771
const int parent_level_index= j-i;
772
BVHNode* parent = branches_array + j;
773
int nth_positions[ MAX_TREETYPE + 1];
755
const int parent_level_index = j - i;
756
BVHNode *parent = branches_array + j;
757
int nth_positions[MAX_TREETYPE + 1];
776
760
int parent_leafs_begin = implicit_leafs_index(&data, depth, parent_level_index);
777
int parent_leafs_end = implicit_leafs_index(&data, depth, parent_level_index+1);
761
int parent_leafs_end = implicit_leafs_index(&data, depth, parent_level_index + 1);
779
//This calculates the bounding box of this branch
780
//and chooses the largest axis as the axis to divide leafs
763
/* This calculates the bounding box of this branch
764
* and chooses the largest axis as the axis to divide leafs */
781
765
refit_kdop_hull(tree, parent, parent_leafs_begin, parent_leafs_end);
782
766
split_axis = get_largest_axis(parent->bv);
784
//Save split axis (this can be used on raytracing to speedup the query time)
768
/* Save split axis (this can be used on raytracing to speedup the query time) */
785
769
parent->main_axis = split_axis / 2;
787
//Split the childs along the split_axis, note: its not needed to sort the whole leafs array
788
//Only to assure that the elements are partioned on a way that each child takes the elements
789
//it would take in case the whole array was sorted.
790
//Split_leafs takes care of that "sort" problem.
791
nth_positions[ 0] = parent_leafs_begin;
771
/* Split the childs along the split_axis, note: its not needed to sort the whole leafs array
772
* Only to assure that the elements are partitioned on a way that each child takes the elements
773
* it would take in case the whole array was sorted.
774
* Split_leafs takes care of that "sort" problem. */
775
nth_positions[0] = parent_leafs_begin;
792
776
nth_positions[tree_type] = parent_leafs_end;
793
777
for (k = 1; k < tree_type; k++) {
794
778
int child_index = j * tree_type + tree_offset + k;
795
int child_level_index = child_index - first_of_next_level; //child level index
796
nth_positions[k] = implicit_leafs_index(&data, depth+1, child_level_index);
779
int child_level_index = child_index - first_of_next_level; /* child level index */
780
nth_positions[k] = implicit_leafs_index(&data, depth + 1, child_level_index);
799
783
split_leafs(leafs_array, nth_positions, tree_type, split_axis);
802
//Setup children and totnode counters
803
//Not really needed but currently most of BVH code relies on having an explicit children structure
786
/* Setup children and totnode counters
787
* Not really needed but currently most of BVH code relies on having an explicit children structure */
804
788
for (k = 0; k < tree_type; k++) {
805
789
int child_index = j * tree_type + tree_offset + k;
806
int child_level_index = child_index - first_of_next_level; //child level index
790
int child_level_index = child_index - first_of_next_level; /* child level index */
808
int child_leafs_begin = implicit_leafs_index(&data, depth+1, child_level_index);
809
int child_leafs_end = implicit_leafs_index(&data, depth+1, child_level_index+1);
792
int child_leafs_begin = implicit_leafs_index(&data, depth + 1, child_level_index);
793
int child_leafs_end = implicit_leafs_index(&data, depth + 1, child_level_index + 1);
811
795
if (child_leafs_end - child_leafs_begin > 1) {
812
796
parent->children[k] = branches_array + child_index;
813
797
parent->children[k]->parent = parent;
815
799
else if (child_leafs_end - child_leafs_begin == 1) {
816
parent->children[k] = leafs_array[ child_leafs_begin ];
800
parent->children[k] = leafs_array[child_leafs_begin];
817
801
parent->children[k]->parent = parent;
823
parent->totnode = k+1;
807
parent->totnode = k + 1;
948
BVHNode* branches_array = tree->nodearray + tree->totleaf;
949
BVHNode** leafs_array = tree->nodes;
926
BVHNode *branches_array = tree->nodearray + tree->totleaf;
927
BVHNode **leafs_array = tree->nodes;
951
//This function should only be called once (some big bug goes here if its being called more than once per tree)
929
/* This function should only be called once (some big bug goes here if its being called more than once per tree) */
952
930
assert(tree->totbranch == 0);
954
//Build the implicit tree
932
/* Build the implicit tree */
955
933
non_recursive_bvh_div_nodes(tree, branches_array, leafs_array, tree->totleaf);
957
//current code expects the branches to be linked to the nodes array
958
//we perform that linkage here
935
/*current code expects the branches to be linked to the nodes array
936
*we perform that linkage here */
959
937
tree->totbranch = implicit_needed_branches(tree->tree_type, tree->totleaf);
960
938
for (i = 0; i < tree->totbranch; i++)
961
939
tree->nodes[tree->totleaf + i] = branches_array + i;
963
941
build_skip_links(tree, tree->nodes[tree->totleaf], NULL, NULL);
964
//bvhtree_info(tree);
942
/* bvhtree_info(tree); */
967
int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints)
945
int BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
970
948
BVHNode *node = NULL;
972
// insert should only possible as long as tree->totbranch is 0
950
/* insert should only possible as long as tree->totbranch is 0 */
973
951
if (tree->totbranch > 0)
976
if (tree->totleaf+1 >= MEM_allocN_len(tree->nodes)/sizeof(*(tree->nodes)))
954
if (tree->totleaf + 1 >= MEM_allocN_len(tree->nodes) / sizeof(*(tree->nodes)))
979
// TODO check if have enough nodes in array
957
/* TODO check if have enough nodes in array */
981
959
node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]);
984
962
create_kdop_hull(tree, node, co, numpoints, 0);
987
// inflate the bv with some epsilon
988
for (i = tree->start_axis; i < tree->stop_axis; i++)
990
node->bv[(2 * i)] -= tree->epsilon; // minimum
991
node->bv[(2 * i) + 1] += tree->epsilon; // maximum
965
/* inflate the bv with some epsilon */
966
for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
967
node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */
968
node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */
998
// call before BLI_bvhtree_update_tree()
999
int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints)
975
/* call before BLI_bvhtree_update_tree() */
976
int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
1002
BVHNode *node= NULL;
978
BVHNode *node = NULL;
1004
// check if index exists
981
/* check if index exists */
1005
982
if (index > tree->totleaf)
1046
1022
* BLI_bvhtree_overlap
1048
// overlap - is it possbile for 2 bv's to collide ?
1049
static int tree_overlap(BVHNode *node1, BVHNode *node2, int start_axis, int stop_axis)
1024
* overlap - is it possible for 2 bv's to collide ? */
1025
static int tree_overlap(BVHNode *node1, BVHNode *node2, axis_t start_axis, axis_t stop_axis)
1051
1027
float *bv1 = node1->bv;
1052
1028
float *bv2 = node2->bv;
1054
float *bv1_end = bv1 + (stop_axis<<1);
1030
float *bv1_end = bv1 + (stop_axis << 1);
1056
bv1 += start_axis<<1;
1057
bv2 += start_axis<<1;
1032
bv1 += start_axis << 1;
1033
bv2 += start_axis << 1;
1059
// test all axis if min + max overlap
1060
for (; bv1 != bv1_end; bv1+=2, bv2+=2)
1062
if ((*(bv1) > *(bv2 + 1)) || (*(bv2) > *(bv1 + 1)))
1035
/* test all axis if min + max overlap */
1036
for (; bv1 != bv1_end; bv1 += 2, bv2 += 2) {
1037
if ((*(bv1) > *(bv2 + 1)) || (*(bv2) > *(bv1 + 1)))
1069
1044
static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2)
1073
if (tree_overlap(node1, node2, data->start_axis, data->stop_axis))
1075
// check if node1 is a leaf
1076
if (!node1->totnode)
1078
// check if node2 is a leaf
1079
if (!node2->totnode)
1048
if (tree_overlap(node1, node2, data->start_axis, data->stop_axis)) {
1049
/* check if node1 is a leaf */
1050
if (!node1->totnode) {
1051
/* check if node2 is a leaf */
1052
if (!node2->totnode) {
1054
if (node1 == node2) {
1087
if (data->i >= data->max_overlap)
1089
// try to make alloc'ed memory bigger
1090
data->overlap = realloc(data->overlap, sizeof(BVHTreeOverlap)*data->max_overlap*2);
1058
if (data->i >= data->max_overlap) {
1059
/* try to make alloc'ed memory bigger */
1060
data->overlap = realloc(data->overlap, sizeof(BVHTreeOverlap) * data->max_overlap * 2);
1062
if (!data->overlap) {
1094
1063
printf("Out of Memory in traverse\n");
1097
1066
data->max_overlap *= 2;
1100
// both leafs, insert overlap!
1069
/* both leafs, insert overlap! */
1101
1070
data->overlap[data->i].indexA = node1->index;
1102
1071
data->overlap[data->i].indexB = node2->index;
1108
for (j = 0; j < data->tree2->tree_type; j++)
1076
for (j = 0; j < data->tree2->tree_type; j++) {
1110
1077
if (node2->children[j])
1111
1078
traverse(data, node1, node2->children[j]);
1118
for (j = 0; j < data->tree2->tree_type; j++)
1083
for (j = 0; j < data->tree2->tree_type; j++) {
1120
1084
if (node1->children[j])
1121
1085
traverse(data, node1->children[j], node2);
1132
1096
BVHTreeOverlap *overlap = NULL, *to = NULL;
1133
1097
BVHOverlapData **data;
1135
// check for compatibility of both trees (can't compare 14-DOP with 18-DOP)
1099
/* check for compatibility of both trees (can't compare 14-DOP with 18-DOP) */
1136
1100
if ((tree1->axis != tree2->axis) && (tree1->axis == 14 || tree2->axis == 14) && (tree1->axis == 18 || tree2->axis == 18))
1139
// fast check root nodes for collision before doing big splitting + traversal
1140
if (!tree_overlap(tree1->nodes[tree1->totleaf], tree2->nodes[tree2->totleaf], MIN2(tree1->start_axis, tree2->start_axis), MIN2(tree1->stop_axis, tree2->stop_axis)))
1103
/* fast check root nodes for collision before doing big splitting + traversal */
1104
if (!tree_overlap(tree1->nodes[tree1->totleaf], tree2->nodes[tree2->totleaf],
1105
min_axis(tree1->start_axis, tree2->start_axis),
1106
min_axis(tree1->stop_axis, tree2->stop_axis)))
1143
data = MEM_callocN(sizeof(BVHOverlapData *)* tree1->tree_type, "BVHOverlapData_star");
1111
data = MEM_callocN(sizeof(BVHOverlapData *) * tree1->tree_type, "BVHOverlapData_star");
1145
for (j = 0; j < tree1->tree_type; j++)
1113
for (j = 0; j < tree1->tree_type; j++) {
1147
1114
data[j] = (BVHOverlapData *)MEM_callocN(sizeof(BVHOverlapData), "BVHOverlapData");
1149
// init BVHOverlapData
1150
data[j]->overlap = (BVHTreeOverlap *)malloc(sizeof(BVHTreeOverlap)*MAX2(tree1->totleaf, tree2->totleaf));
1116
/* init BVHOverlapData */
1117
data[j]->overlap = (BVHTreeOverlap *)malloc(sizeof(BVHTreeOverlap) * max_ii(tree1->totleaf, tree2->totleaf));
1151
1118
data[j]->tree1 = tree1;
1152
1119
data[j]->tree2 = tree2;
1153
data[j]->max_overlap = MAX2(tree1->totleaf, tree2->totleaf);
1120
data[j]->max_overlap = max_ii(tree1->totleaf, tree2->totleaf);
1154
1121
data[j]->i = 0;
1155
data[j]->start_axis = MIN2(tree1->start_axis, tree2->start_axis);
1156
data[j]->stop_axis = MIN2(tree1->stop_axis, tree2->stop_axis );
1122
data[j]->start_axis = min_axis(tree1->start_axis, tree2->start_axis);
1123
data[j]->stop_axis = min_axis(tree1->stop_axis, tree2->stop_axis);
1159
1126
#pragma omp parallel for private(j) schedule(static)
1160
for (j = 0; j < MIN2(tree1->tree_type, tree1->nodes[tree1->totleaf]->totnode); j++)
1127
for (j = 0; j < MIN2(tree1->tree_type, tree1->nodes[tree1->totleaf]->totnode); j++) {
1162
1128
traverse(data[j], tree1->nodes[tree1->totleaf]->children[j], tree2->nodes[tree2->totleaf]);
1165
1131
for (j = 0; j < tree1->tree_type; j++)
1166
1132
total += data[j]->i;
1168
to = overlap = (BVHTreeOverlap *)MEM_callocN(sizeof(BVHTreeOverlap)*total, "BVHTreeOverlap");
1134
to = overlap = (BVHTreeOverlap *)MEM_callocN(sizeof(BVHTreeOverlap) * total, "BVHTreeOverlap");
1170
for (j = 0; j < tree1->tree_type; j++)
1172
memcpy(to, data[j]->overlap, data[j]->i*sizeof(BVHTreeOverlap));
1136
for (j = 0; j < tree1->tree_type; j++) {
1137
memcpy(to, data[j]->overlap, data[j]->i * sizeof(BVHTreeOverlap));
1176
for (j = 0; j < tree1->tree_type; j++)
1141
for (j = 0; j < tree1->tree_type; j++) {
1178
1142
free(data[j]->overlap);
1179
1143
MEM_freeN(data[j]);
1226
typedef struct NodeDistance
1189
typedef struct NodeDistance {
1231
1193
} NodeDistance;
1233
#define NodeDistance_priority(a,b) ( (a).dist < (b).dist )
1235
// TODO: use a priority queue to reduce the number of nodes looked on
1195
/* TODO: use a priority queue to reduce the number of nodes looked on */
1236
1196
static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node)
1238
if (node->totnode == 0)
1198
if (node->totnode == 0) {
1240
1199
if (data->callback)
1241
data->callback(data->userdata , node->index, data->co, &data->nearest);
1244
data->nearest.index = node->index;
1245
data->nearest.dist = calc_nearest_point(data->proj, node, data->nearest.co);
1200
data->callback(data->userdata, node->index, data->co, &data->nearest);
1202
data->nearest.index = node->index;
1203
data->nearest.dist = calc_nearest_point(data->proj, node, data->nearest.co);
1250
//Better heuristic to pick the closest node to dive on
1207
/* Better heuristic to pick the closest node to dive on */
1252
1209
float nearest[3];
1254
if (data->proj[ node->main_axis ] <= node->children[0]->bv[node->main_axis*2+1])
1211
if (data->proj[node->main_axis] <= node->children[0]->bv[node->main_axis * 2 + 1]) {
1257
for (i=0; i != node->totnode; i++)
1259
if ( calc_nearest_point(data->proj, node->children[i], nearest) >= data->nearest.dist) continue;
1213
for (i = 0; i != node->totnode; i++) {
1214
if (calc_nearest_point(data->proj, node->children[i], nearest) >= data->nearest.dist) continue;
1260
1215
dfs_find_nearest_dfs(data, node->children[i]);
1265
for (i=node->totnode-1; i >= 0 ; i--)
1267
if ( calc_nearest_point(data->proj, node->children[i], nearest) >= data->nearest.dist) continue;
1219
for (i = node->totnode - 1; i >= 0; i--) {
1220
if (calc_nearest_point(data->proj, node->children[i], nearest) >= data->nearest.dist) continue;
1268
1221
dfs_find_nearest_dfs(data, node->children[i]);
1238
#define DEFAULT_FIND_NEAREST_HEAP_SIZE 1024
1240
#define NodeDistance_priority(a, b) ((a).dist < (b).dist)
1284
1242
static void NodeDistance_push_heap(NodeDistance *heap, int heap_size)
1285
1243
PUSH_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size)
1287
1245
static void NodeDistance_pop_heap(NodeDistance *heap, int heap_size)
1288
1246
POP_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size)
1290
//NN function that uses an heap.. this functions leads to an optimal number of min-distance
1291
//but for normal tri-faces and BV 6-dop.. a simple dfs with local heuristics (as implemented
1292
//in source/blender/blenkernel/intern/shrinkwrap.c) works faster.
1294
//It may make sense to use this function if the callback queries are very slow.. or if its impossible
1295
//to get a nice heuristic
1297
//this function uses "malloc/free" instead of the MEM_* because it intends to be openmp safe
1248
/* NN function that uses an heap.. this functions leads to an optimal number of min-distance
1249
* but for normal tri-faces and BV 6-dop.. a simple dfs with local heuristics (as implemented
1250
* in source/blender/blenkernel/intern/shrinkwrap.c) works faster.
1252
* It may make sense to use this function if the callback queries are very slow.. or if its impossible
1253
* to get a nice heuristic
1255
* this function uses "malloc/free" instead of the MEM_* because it intends to be openmp safe */
1298
1256
static void bfs_find_nearest(BVHNearestData *data, BVHNode *node)
1301
1259
NodeDistance default_heap[DEFAULT_FIND_NEAREST_HEAP_SIZE];
1302
NodeDistance *heap=default_heap, current;
1303
int heap_size = 0, max_heap_size = sizeof(default_heap)/sizeof(default_heap[0]);
1260
NodeDistance *heap = default_heap, current;
1261
int heap_size = 0, max_heap_size = sizeof(default_heap) / sizeof(default_heap[0]);
1304
1262
float nearest[3];
1306
1264
int callbacks = 0, push_heaps = 0;
1491
//ray-bv is really fast.. and simple tests revealed its worth to test it
1492
//before calling the ray-primitive functions
1440
/* ray-bv is really fast.. and simple tests revealed its worth to test it
1441
* before calling the ray-primitive functions */
1493
1442
/* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
1494
1443
float dist = (data->ray.radius > 0.0f) ? ray_nearest_hit(data, node->bv) : fast_ray_nearest_hit(data, node);
1495
1444
if (dist >= data->hit.dist) return;
1497
if (node->totnode == 0)
1446
if (node->totnode == 0) {
1447
if (data->callback) {
1500
1448
data->callback(data->userdata, node->index, &data->ray, &data->hit);
1503
data->hit.index = node->index;
1451
data->hit.index = node->index;
1504
1452
data->hit.dist = dist;
1505
1453
madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist);
1510
//pick loop direction to dive into the tree (based on ray direction and split axis)
1511
if (data->ray_dot_axis[ (int)node->main_axis ] > 0.0f)
1513
for (i=0; i != node->totnode; i++)
1457
/* pick loop direction to dive into the tree (based on ray direction and split axis) */
1458
if (data->ray_dot_axis[(int)node->main_axis] > 0.0f) {
1459
for (i = 0; i != node->totnode; i++) {
1515
1460
dfs_raycast(data, node->children[i]);
1520
for (i=node->totnode-1; i >= 0; i--)
1464
for (i = node->totnode - 1; i >= 0; i--) {
1522
1465
dfs_raycast(data, node->children[i]);
1576
1519
normalize_v3(data.ray.direction);
1521
for (i = 0; i < 3; i++) {
1580
1522
data.ray_dot_axis[i] = dot_v3v3(data.ray.direction, KDOP_AXES[i]);
1581
1523
data.idot_axis[i] = 1.0f / data.ray_dot_axis[i];
1583
if (fabsf(data.ray_dot_axis[i]) < FLT_EPSILON)
1525
if (fabsf(data.ray_dot_axis[i]) < FLT_EPSILON) {
1585
1526
data.ray_dot_axis[i] = 0.0;
1587
data.index[2*i] = data.idot_axis[i] < 0.0f ? 1 : 0;
1588
data.index[2*i+1] = 1 - data.index[2*i];
1589
data.index[2*i] += 2*i;
1590
data.index[2*i+1] += 2*i;
1528
data.index[2 * i] = data.idot_axis[i] < 0.0f ? 1 : 0;
1529
data.index[2 * i + 1] = 1 - data.index[2 * i];
1530
data.index[2 * i] += 2 * i;
1531
data.index[2 * i + 1] += 2 * i;
1595
memcpy( &data.hit, hit, sizeof(*hit) );
1536
memcpy(&data.hit, hit, sizeof(*hit));
1598
1538
data.hit.index = -1;
1599
1539
data.hit.dist = FLT_MAX;
1604
1543
dfs_raycast(&data, root);
1605
1544
// iterative_raycast(&data, root);
1610
memcpy( hit, &data.hit, sizeof(*hit) );
1549
memcpy(hit, &data.hit, sizeof(*hit));
1612
1551
return data.hit.index;
1615
float BLI_bvhtree_bb_raycast(float *bv, const float light_start[3], const float light_end[3], float pos[3])
1554
float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3])
1617
1556
BVHRayCastData data;
1620
1559
data.hit.dist = FLT_MAX;
1622
// get light direction
1561
/* get light direction */
1623
1562
data.ray.direction[0] = light_end[0] - light_start[0];
1624
1563
data.ray.direction[1] = light_end[1] - light_start[1];
1625
1564
data.ray.direction[2] = light_end[2] - light_start[2];