bvh_split.inc 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. void _split_inform_references(uint32_t p_node_id) {
  2. TNode &node = _nodes[p_node_id];
  3. TLeaf &leaf = _node_get_leaf(node);
  4. for (int n = 0; n < leaf.num_items; n++) {
  5. uint32_t ref_id = leaf.get_item_ref_id(n);
  6. ItemRef &ref = _refs[ref_id];
  7. ref.tnode_id = p_node_id;
  8. ref.item_id = n;
  9. }
  10. }
  11. void _split_leaf_sort_groups_simple(int &num_a, int &num_b, uint16_t *group_a, uint16_t *group_b, const BVHABB_CLASS *temp_bounds, const BVHABB_CLASS full_bound) {
  12. // special case for low leaf sizes .. should static compile out
  13. if constexpr (MAX_ITEMS < 4) {
  14. uint32_t ind = group_a[0];
  15. // add to b
  16. group_b[num_b++] = ind;
  17. // remove from a
  18. group_a[0] = group_a[num_a - 1];
  19. num_a--;
  20. return;
  21. }
  22. POINT center = full_bound.calculate_center();
  23. POINT size = full_bound.calculate_size();
  24. int order[POINT::AXIS_COUNT];
  25. order[0] = size.min_axis_index();
  26. order[POINT::AXIS_COUNT - 1] = size.max_axis_index();
  27. static_assert(POINT::AXIS_COUNT <= 3, "BVH POINT::AXIS_COUNT has unexpected size");
  28. if constexpr (POINT::AXIS_COUNT == 3) {
  29. order[1] = 3 - (order[0] + order[2]);
  30. }
  31. // simplest case, split on the longest axis
  32. int split_axis = order[0];
  33. for (int a = 0; a < num_a; a++) {
  34. uint32_t ind = group_a[a];
  35. if (temp_bounds[ind].min.coord[split_axis] > center.coord[split_axis]) {
  36. // add to b
  37. group_b[num_b++] = ind;
  38. // remove from a
  39. group_a[a] = group_a[num_a - 1];
  40. num_a--;
  41. // do this one again, as it has been replaced
  42. a--;
  43. }
  44. }
  45. // detect when split on longest axis failed
  46. int min_threshold = MAX_ITEMS / 4;
  47. int min_group_size[POINT::AXIS_COUNT];
  48. min_group_size[0] = MIN(num_a, num_b);
  49. if (min_group_size[0] < min_threshold) {
  50. // slow but sure .. first move everything back into a
  51. for (int b = 0; b < num_b; b++) {
  52. group_a[num_a++] = group_b[b];
  53. }
  54. num_b = 0;
  55. // now calculate the best split
  56. for (int axis = 1; axis < POINT::AXIS_COUNT; axis++) {
  57. split_axis = order[axis];
  58. int count = 0;
  59. for (int a = 0; a < num_a; a++) {
  60. uint32_t ind = group_a[a];
  61. if (temp_bounds[ind].min.coord[split_axis] > center.coord[split_axis]) {
  62. count++;
  63. }
  64. }
  65. min_group_size[axis] = MIN(count, num_a - count);
  66. } // for axis
  67. // best axis
  68. int best_axis = 0;
  69. int best_min = min_group_size[0];
  70. for (int axis = 1; axis < POINT::AXIS_COUNT; axis++) {
  71. if (min_group_size[axis] > best_min) {
  72. best_min = min_group_size[axis];
  73. best_axis = axis;
  74. }
  75. }
  76. // now finally do the split
  77. if (best_min > 0) {
  78. split_axis = order[best_axis];
  79. for (int a = 0; a < num_a; a++) {
  80. uint32_t ind = group_a[a];
  81. if (temp_bounds[ind].min.coord[split_axis] > center.coord[split_axis]) {
  82. // add to b
  83. group_b[num_b++] = ind;
  84. // remove from a
  85. group_a[a] = group_a[num_a - 1];
  86. num_a--;
  87. // do this one again, as it has been replaced
  88. a--;
  89. }
  90. }
  91. } // if there was a split!
  92. } // if the longest axis wasn't a good split
  93. // special case, none crossed threshold
  94. if (!num_b) {
  95. uint32_t ind = group_a[0];
  96. // add to b
  97. group_b[num_b++] = ind;
  98. // remove from a
  99. group_a[0] = group_a[num_a - 1];
  100. num_a--;
  101. }
  102. // opposite problem! :)
  103. if (!num_a) {
  104. uint32_t ind = group_b[0];
  105. // add to a
  106. group_a[num_a++] = ind;
  107. // remove from b
  108. group_b[0] = group_b[num_b - 1];
  109. num_b--;
  110. }
  111. }
  112. void _split_leaf_sort_groups(int &num_a, int &num_b, uint16_t *group_a, uint16_t *group_b, const BVHABB_CLASS *temp_bounds) {
  113. BVHABB_CLASS groupb_aabb;
  114. groupb_aabb.set_to_max_opposite_extents();
  115. for (int n = 0; n < num_b; n++) {
  116. int which = group_b[n];
  117. groupb_aabb.merge(temp_bounds[which]);
  118. }
  119. BVHABB_CLASS groupb_aabb_new;
  120. BVHABB_CLASS rest_aabb;
  121. float best_size = FLT_MAX;
  122. int best_candidate = -1;
  123. // find most likely from a to move into b
  124. for (int check = 0; check < num_a; check++) {
  125. rest_aabb.set_to_max_opposite_extents();
  126. groupb_aabb_new = groupb_aabb;
  127. // find aabb of all the rest
  128. for (int rest = 0; rest < num_a; rest++) {
  129. if (rest == check) {
  130. continue;
  131. }
  132. int which = group_a[rest];
  133. rest_aabb.merge(temp_bounds[which]);
  134. }
  135. groupb_aabb_new.merge(temp_bounds[group_a[check]]);
  136. // now compare the sizes
  137. float size = groupb_aabb_new.get_area() + rest_aabb.get_area();
  138. if (size < best_size) {
  139. best_size = size;
  140. best_candidate = check;
  141. }
  142. }
  143. // we should now have the best, move it from group a to group b
  144. group_b[num_b++] = group_a[best_candidate];
  145. // remove best candidate from group a
  146. num_a--;
  147. group_a[best_candidate] = group_a[num_a];
  148. }
  149. uint32_t split_leaf(uint32_t p_node_id, const BVHABB_CLASS &p_added_item_aabb) {
  150. return split_leaf_complex(p_node_id, p_added_item_aabb);
  151. }
  152. // aabb is the new inserted node
  153. uint32_t split_leaf_complex(uint32_t p_node_id, const BVHABB_CLASS &p_added_item_aabb) {
  154. VERBOSE_PRINT("split_leaf");
  155. // note the tnode before and AFTER splitting may be a different address
  156. // in memory because the vector could get relocated. So we need to reget
  157. // the tnode after the split
  158. BVH_ASSERT(_nodes[p_node_id].is_leaf());
  159. // first create child leaf nodes
  160. uint32_t *child_ids = (uint32_t *)alloca(sizeof(uint32_t) * MAX_CHILDREN);
  161. for (int n = 0; n < MAX_CHILDREN; n++) {
  162. // create node children
  163. TNode *child_node = _nodes.request(child_ids[n]);
  164. child_node->clear();
  165. // back link to parent
  166. child_node->parent_id = p_node_id;
  167. // make each child a leaf node
  168. node_make_leaf(child_ids[n]);
  169. }
  170. // don't get any leaves or nodes till AFTER the split
  171. TNode &tnode = _nodes[p_node_id];
  172. uint32_t orig_leaf_id = tnode.get_leaf_id();
  173. const TLeaf &orig_leaf = _node_get_leaf(tnode);
  174. // store the final child ids
  175. for (int n = 0; n < MAX_CHILDREN; n++) {
  176. tnode.children[n] = child_ids[n];
  177. }
  178. // mark as no longer a leaf node
  179. tnode.num_children = MAX_CHILDREN;
  180. // 2 groups, A and B, and assign children to each to split equally
  181. int max_children = orig_leaf.num_items + 1; // plus 1 for the wildcard .. the item being added
  182. //CRASH_COND(max_children > MAX_CHILDREN);
  183. uint16_t *group_a = (uint16_t *)alloca(sizeof(uint16_t) * max_children);
  184. uint16_t *group_b = (uint16_t *)alloca(sizeof(uint16_t) * max_children);
  185. // we are copying the ABBs. This is ugly, but we need one extra for the inserted item...
  186. BVHABB_CLASS *temp_bounds = (BVHABB_CLASS *)alloca(sizeof(BVHABB_CLASS) * max_children);
  187. int num_a = max_children;
  188. int num_b = 0;
  189. // setup - start with all in group a
  190. for (int n = 0; n < orig_leaf.num_items; n++) {
  191. group_a[n] = n;
  192. temp_bounds[n] = orig_leaf.get_aabb(n);
  193. }
  194. // wildcard
  195. int wildcard = orig_leaf.num_items;
  196. group_a[wildcard] = wildcard;
  197. temp_bounds[wildcard] = p_added_item_aabb;
  198. // we can choose here either an equal split, or just 1 in the new leaf
  199. _split_leaf_sort_groups_simple(num_a, num_b, group_a, group_b, temp_bounds, tnode.aabb);
  200. uint32_t wildcard_node = BVHCommon::INVALID;
  201. // now there should be equal numbers in both groups
  202. for (int n = 0; n < num_a; n++) {
  203. int which = group_a[n];
  204. if (which != wildcard) {
  205. const BVHABB_CLASS &source_item_aabb = orig_leaf.get_aabb(which);
  206. uint32_t source_item_ref_id = orig_leaf.get_item_ref_id(which);
  207. //const Item &source_item = orig_leaf.get_item(which);
  208. _node_add_item(tnode.children[0], source_item_ref_id, source_item_aabb);
  209. } else {
  210. wildcard_node = tnode.children[0];
  211. }
  212. }
  213. for (int n = 0; n < num_b; n++) {
  214. int which = group_b[n];
  215. if (which != wildcard) {
  216. const BVHABB_CLASS &source_item_aabb = orig_leaf.get_aabb(which);
  217. uint32_t source_item_ref_id = orig_leaf.get_item_ref_id(which);
  218. //const Item &source_item = orig_leaf.get_item(which);
  219. _node_add_item(tnode.children[1], source_item_ref_id, source_item_aabb);
  220. } else {
  221. wildcard_node = tnode.children[1];
  222. }
  223. }
  224. // now remove all items from the parent and replace with the child nodes
  225. _leaves.free(orig_leaf_id);
  226. // we should keep the references up to date!
  227. for (int n = 0; n < MAX_CHILDREN; n++) {
  228. _split_inform_references(tnode.children[n]);
  229. }
  230. refit_upward(p_node_id);
  231. BVH_ASSERT(wildcard_node != BVHCommon::INVALID);
  232. return wildcard_node;
  233. }