int encodeIdx() const { return (node->is_leaf())? ~idx: idx; }
CCL_NAMESPACE_BEGIN /* BVH Node */ int BVHNode::getSubtreeSize(BVH_STAT stat) const { int cnt = 0; switch(stat) { case BVH_STAT_NODE_COUNT: cnt = 1; break; case BVH_STAT_LEAF_COUNT: cnt = is_leaf() ? 1 : 0; break; case BVH_STAT_INNER_COUNT: cnt = is_leaf() ? 0 : 1; break; case BVH_STAT_TRIANGLE_COUNT: cnt = is_leaf() ? reinterpret_cast<const LeafNode*>(this)->num_triangles() : 0; break; case BVH_STAT_CHILDNODE_COUNT: cnt = num_children(); break; case BVH_STAT_QNODE_COUNT: cnt = 1; for(int i = 0; i < num_children(); i++) { BVHNode *node = get_child(i); if(node->is_leaf()) { cnt += 1; } else { for(int j = 0; j < node->num_children(); j++) { cnt += node->get_child(j)->getSubtreeSize(stat); } } } return cnt; case BVH_STAT_ALIGNED_COUNT: if(!is_unaligned) { cnt = 1; } break; case BVH_STAT_UNALIGNED_COUNT: if(is_unaligned) { cnt = 1; } break; case BVH_STAT_ALIGNED_INNER_COUNT: if(!is_leaf()) { bool has_unaligned = false; for(int j = 0; j < num_children(); j++) { has_unaligned |= get_child(j)->is_unaligned; } cnt += has_unaligned? 0: 1; } break; case BVH_STAT_UNALIGNED_INNER_COUNT: if(!is_leaf()) { bool has_unaligned = false; for(int j = 0; j < num_children(); j++) { has_unaligned |= get_child(j)->is_unaligned; } cnt += has_unaligned? 1: 0; } break; case BVH_STAT_ALIGNED_INNER_QNODE_COUNT: { bool has_unaligned = false; for(int i = 0; i < num_children(); i++) { BVHNode *node = get_child(i); if(node->is_leaf()) { has_unaligned |= node->is_unaligned; } else { for(int j = 0; j < node->num_children(); j++) { cnt += node->get_child(j)->getSubtreeSize(stat); has_unaligned |= node->get_child(j)->is_unaligned; } } } cnt += has_unaligned? 0: 1; } return cnt; case BVH_STAT_UNALIGNED_INNER_QNODE_COUNT: { bool has_unaligned = false; for(int i = 0; i < num_children(); i++) { BVHNode *node = get_child(i); if(node->is_leaf()) { has_unaligned |= node->is_unaligned; } else { for(int j = 0; j < node->num_children(); j++) { cnt += node->get_child(j)->getSubtreeSize(stat); has_unaligned |= node->get_child(j)->is_unaligned; } } } cnt += has_unaligned? 1: 0; } return cnt; case BVH_STAT_ALIGNED_LEAF_COUNT: cnt = (is_leaf() && !is_unaligned) ? 1 : 0; break; case BVH_STAT_UNALIGNED_LEAF_COUNT: cnt = (is_leaf() && is_unaligned) ? 1 : 0; break; case BVH_STAT_DEPTH: if(is_leaf()) { cnt = 1; } else { for(int i = 0; i < num_children(); i++) { cnt = max(cnt, get_child(i)->getSubtreeSize(stat)); } cnt += 1; } return cnt; default: assert(0); /* unknown mode */ } if(!is_leaf()) for(int i = 0; i < num_children(); i++) cnt += get_child(i)->getSubtreeSize(stat); return cnt; }