Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/bvh/bvh_node.h')
-rw-r--r--intern/cycles/bvh/bvh_node.h129
1 files changed, 102 insertions, 27 deletions
diff --git a/intern/cycles/bvh/bvh_node.h b/intern/cycles/bvh/bvh_node.h
index 65d5df01158..8a2cffeb056 100644
--- a/intern/cycles/bvh/bvh_node.h
+++ b/intern/cycles/bvh/bvh_node.h
@@ -29,18 +29,13 @@ enum BVH_STAT {
BVH_STAT_LEAF_COUNT,
BVH_STAT_TRIANGLE_COUNT,
BVH_STAT_CHILDNODE_COUNT,
- BVH_STAT_QNODE_COUNT,
BVH_STAT_ALIGNED_COUNT,
BVH_STAT_UNALIGNED_COUNT,
BVH_STAT_ALIGNED_INNER_COUNT,
BVH_STAT_UNALIGNED_INNER_COUNT,
- BVH_STAT_ALIGNED_INNER_QNODE_COUNT,
- BVH_STAT_UNALIGNED_INNER_QNODE_COUNT,
BVH_STAT_ALIGNED_LEAF_COUNT,
BVH_STAT_UNALIGNED_LEAF_COUNT,
BVH_STAT_DEPTH,
- BVH_STAT_ONODE_COUNT,
- BVH_STAT_UNALIGNED_INNER_ONODE_COUNT,
};
class BVHParams;
@@ -48,13 +43,6 @@ class BVHParams;
class BVHNode
{
public:
- BVHNode() : is_unaligned(false),
- aligned_space(NULL),
- time_from(0.0f),
- time_to(1.0f)
- {
- }
-
virtual ~BVHNode()
{
delete aligned_space;
@@ -85,6 +73,19 @@ public:
return *aligned_space;
}
+ inline bool has_unaligned() const
+ {
+ if(is_leaf()) {
+ return false;
+ }
+ for(int i = 0; i < num_children(); ++i) {
+ if(get_child(i)->is_unaligned) {
+ return true;
+ }
+ }
+ return false;
+ }
+
// Subtree functions
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const;
float computeSubtreeSAHCost(const BVHParams& p, float probability = 1.0f) const;
@@ -105,56 +106,130 @@ public:
Transform *aligned_space;
float time_from, time_to;
+
+protected:
+ explicit BVHNode(const BoundBox& bounds)
+ : bounds(bounds),
+ visibility(0),
+ is_unaligned(false),
+ aligned_space(NULL),
+ time_from(0.0f),
+ time_to(1.0f)
+ {
+ }
+
+ explicit BVHNode(const BVHNode& other)
+ : bounds(other.bounds),
+ visibility(other.visibility),
+ is_unaligned(other.is_unaligned),
+ aligned_space(NULL),
+ time_from(other.time_from),
+ time_to(other.time_to)
+ {
+ if(other.aligned_space != NULL) {
+ assert(other.is_unaligned);
+ aligned_space = new Transform();
+ *aligned_space = *other.aligned_space;
+ }
+ else {
+ assert(!other.is_unaligned);
+ }
+ }
};
class InnerNode : public BVHNode
{
public:
+ static constexpr int kNumMaxChildren = 8;
+
InnerNode(const BoundBox& bounds,
BVHNode* child0,
BVHNode* child1)
+ : BVHNode(bounds),
+ num_children_(2)
{
- this->bounds = bounds;
children[0] = child0;
children[1] = child1;
+ reset_unused_children();
- if(child0 && child1)
- visibility = child0->visibility|child1->visibility;
- else
- visibility = 0; /* happens on build cancel */
+ if(child0 && child1) {
+ visibility = child0->visibility | child1->visibility;
+ }
+ else {
+ /* Happens on build cancel. */
+ visibility = 0;
+ }
}
+ InnerNode(const BoundBox& bounds,
+ BVHNode** children,
+ const int num_children)
+ : BVHNode(bounds),
+ num_children_(num_children)
+ {
+ visibility = 0;
+ time_from = FLT_MAX;
+ time_to = -FLT_MAX;
+ for(int i = 0; i < num_children; ++i) {
+ assert(children[i] != NULL);
+ visibility |= children[i]->visibility;
+ this->children[i] = children[i];
+ time_from = min(time_from, children[i]->time_from);
+ time_to = max(time_to, children[i]->time_to);
+ }
+ reset_unused_children();
+ }
+
+ /* NOTE: This function is only used during binary BVH builder, and it
+ * supposed to be configured to have 2 children which will be filled in in a
+ * bit. But this is important to have children reset to NULL. */
explicit InnerNode(const BoundBox& bounds)
+ : BVHNode(bounds),
+ num_children_(0)
{
- this->bounds = bounds;
+ reset_unused_children();
visibility = 0;
- children[0] = NULL;
- children[1] = NULL;
+ num_children_ = 2;
}
bool is_leaf() const { return false; }
- int num_children() const { return 2; }
- BVHNode *get_child(int i) const{ assert(i>=0 && i<2); return children[i]; }
+ int num_children() const { return num_children_; }
+ BVHNode *get_child(int i) const
+ {
+ assert(i >= 0 && i < num_children_);
+ return children[i];
+ }
void print(int depth) const;
- BVHNode *children[2];
+ int num_children_;
+ BVHNode *children[kNumMaxChildren];
+
+protected:
+ void reset_unused_children()
+ {
+ for(int i = num_children_; i < kNumMaxChildren; ++i) {
+ children[i] = NULL;
+ }
+ }
};
class LeafNode : public BVHNode
{
public:
LeafNode(const BoundBox& bounds, uint visibility, int lo, int hi)
- : lo(lo),
+ : BVHNode(bounds),
+ lo(lo),
hi(hi)
{
this->bounds = bounds;
this->visibility = visibility;
}
- LeafNode(const LeafNode& s)
- : BVHNode()
+ LeafNode(const LeafNode& other)
+ : BVHNode(other),
+ lo(other.lo),
+ hi(other.hi)
{
- *this = s;
}
bool is_leaf() const { return true; }