bvh_refit.inc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. void _debug_node_verify_bound(uint32_t p_node_id) {
  2. TNode &node = _nodes[p_node_id];
  3. BVH_ABB abb_before = node.aabb;
  4. node_update_aabb(node);
  5. BVH_ABB abb_after = node.aabb;
  6. CRASH_COND(abb_before != abb_after);
  7. }
  8. void node_update_aabb(TNode &tnode) {
  9. tnode.aabb.set_to_max_opposite_extents();
  10. tnode.height = 0;
  11. if (!tnode.is_leaf()) {
  12. for (int n = 0; n < tnode.num_children; n++) {
  13. uint32_t child_node_id = tnode.children[n];
  14. // merge with child aabb
  15. const TNode &tchild = _nodes[child_node_id];
  16. tnode.aabb.merge(tchild.aabb);
  17. // do heights at the same time
  18. if (tchild.height > tnode.height)
  19. tnode.height = tchild.height;
  20. }
  21. // the height of a non leaf is always 1 bigger than the biggest child
  22. tnode.height++;
  23. #ifdef BVH_CHECKS
  24. if (!tnode.num_children) {
  25. // the 'blank' aabb will screw up parent aabbs
  26. WARN_PRINT("BVH_Tree::TNode no children, AABB is undefined");
  27. }
  28. #endif
  29. } else {
  30. // leaf
  31. const TLeaf &leaf = _node_get_leaf(tnode);
  32. for (int n = 0; n < leaf.num_items; n++) {
  33. tnode.aabb.merge(leaf.get_aabb(n));
  34. }
  35. // now the leaf items are unexpanded, we expand only in the node AABB
  36. tnode.aabb.expand(_node_expansion);
  37. #ifdef BVH_CHECKS
  38. if (!leaf.num_items) {
  39. // the 'blank' aabb will screw up parent aabbs
  40. WARN_PRINT("BVH_Tree::TLeaf no items, AABB is undefined");
  41. }
  42. #endif
  43. }
  44. }
  45. void refit_all(int p_tree_id) {
  46. refit_downward(_root_node_id[p_tree_id]);
  47. }
  48. void refit_upward(uint32_t p_node_id) {
  49. while (p_node_id != BVHCommon::INVALID) {
  50. TNode &tnode = _nodes[p_node_id];
  51. node_update_aabb(tnode);
  52. p_node_id = tnode.parent_id;
  53. }
  54. }
  55. void refit_upward_and_balance(uint32_t p_node_id) {
  56. while (p_node_id != BVHCommon::INVALID) {
  57. uint32_t before = p_node_id;
  58. p_node_id = _logic_balance(p_node_id);
  59. if (before != p_node_id) {
  60. VERBOSE_PRINT("REBALANCED!");
  61. }
  62. TNode &tnode = _nodes[p_node_id];
  63. // update overall aabb from the children
  64. node_update_aabb(tnode);
  65. p_node_id = tnode.parent_id;
  66. }
  67. }
  68. void refit_downward(uint32_t p_node_id) {
  69. TNode &tnode = _nodes[p_node_id];
  70. // do children first
  71. if (!tnode.is_leaf()) {
  72. for (int n = 0; n < tnode.num_children; n++) {
  73. refit_downward(tnode.children[n]);
  74. }
  75. }
  76. node_update_aabb(tnode);
  77. }
  78. // go down to the leaves, then refit upward
  79. void refit_branch(uint32_t p_node_id) {
  80. // our function parameters to keep on a stack
  81. struct RefitParams {
  82. uint32_t node_id;
  83. };
  84. // most of the iterative functionality is contained in this helper class
  85. BVH_IterativeInfo<RefitParams> ii;
  86. // alloca must allocate the stack from this function, it cannot be allocated in the
  87. // helper class
  88. ii.stack = (RefitParams *)alloca(ii.get_alloca_stacksize());
  89. // seed the stack
  90. ii.get_first()->node_id = p_node_id;
  91. RefitParams rp;
  92. // while there are still more nodes on the stack
  93. while (ii.pop(rp)) {
  94. TNode &tnode = _nodes[rp.node_id];
  95. // do children first
  96. if (!tnode.is_leaf()) {
  97. for (int n = 0; n < tnode.num_children; n++) {
  98. uint32_t child_id = tnode.children[n];
  99. // add to the stack
  100. RefitParams *child = ii.request();
  101. child->node_id = child_id;
  102. }
  103. } else {
  104. // leaf .. only refit upward if dirty
  105. TLeaf &leaf = _node_get_leaf(tnode);
  106. if (leaf.is_dirty()) {
  107. leaf.set_dirty(false);
  108. refit_upward(p_node_id);
  109. }
  110. }
  111. } // while more nodes to pop
  112. }