Blender  V2.93
bvh_node.h
Go to the documentation of this file.
1 /*
2  * Adapted from code copyright 2009-2010 NVIDIA Corporation
3  * Modifications Copyright 2011, Blender Foundation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef __BVH_NODE_H__
19 #define __BVH_NODE_H__
20 
21 #include "util/util_boundbox.h"
22 #include "util/util_types.h"
23 
25 
26 enum BVH_STAT {
39 };
40 
41 class BVHParams;
42 
43 class BVHNode {
44  public:
45  virtual ~BVHNode()
46  {
47  delete aligned_space;
48  }
49 
50  virtual bool is_leaf() const = 0;
51  virtual int num_children() const = 0;
52  virtual BVHNode *get_child(int i) const = 0;
53  virtual int num_triangles() const
54  {
55  return 0;
56  }
57  virtual void print(int depth = 0) const = 0;
58 
60  {
61  is_unaligned = true;
62  if (this->aligned_space == NULL) {
63  this->aligned_space = new Transform(aligned_space);
64  }
65  else {
66  *this->aligned_space = aligned_space;
67  }
68  }
69 
71  {
72  if (aligned_space == NULL) {
73  return transform_identity();
74  }
75  return *aligned_space;
76  }
77 
78  inline bool has_unaligned() const
79  {
80  if (is_leaf()) {
81  return false;
82  }
83  for (int i = 0; i < num_children(); ++i) {
84  if (get_child(i)->is_unaligned) {
85  return true;
86  }
87  }
88  return false;
89  }
90 
91  // Subtree functions
93  float computeSubtreeSAHCost(const BVHParams &p, float probability = 1.0f) const;
94  void deleteSubtree();
95 
97  void update_time();
98 
99  /* Dump the content of the tree as a graphviz file. */
100  void dump_graph(const char *filename);
101 
102  // Properties.
105 
107 
108  /* TODO(sergey): Can be stored as 3x3 matrix, but better to have some
109  * utilities and type defines in util_transform first.
110  */
112 
114 
115  protected:
116  explicit BVHNode(const BoundBox &bounds)
117  : bounds(bounds),
118  visibility(0),
119  is_unaligned(false),
121  time_from(0.0f),
122  time_to(1.0f)
123  {
124  }
125 
126  explicit BVHNode(const BVHNode &other)
127  : bounds(other.bounds),
128  visibility(other.visibility),
129  is_unaligned(other.is_unaligned),
131  time_from(other.time_from),
132  time_to(other.time_to)
133  {
134  if (other.aligned_space != NULL) {
135  assert(other.is_unaligned);
136  aligned_space = new Transform();
137  *aligned_space = *other.aligned_space;
138  }
139  else {
140  assert(!other.is_unaligned);
141  }
142  }
143 };
144 
145 class InnerNode : public BVHNode {
146  public:
147  static constexpr int kNumMaxChildren = 8;
148 
149  InnerNode(const BoundBox &bounds, BVHNode *child0, BVHNode *child1)
151  {
152  children[0] = child0;
153  children[1] = child1;
155 
156  if (child0 && child1) {
157  visibility = child0->visibility | child1->visibility;
158  }
159  else {
160  /* Happens on build cancel. */
161  visibility = 0;
162  }
163  }
164 
167  {
168  visibility = 0;
169  time_from = FLT_MAX;
170  time_to = -FLT_MAX;
171  for (int i = 0; i < num_children; ++i) {
172  assert(children[i] != NULL);
174  this->children[i] = children[i];
177  }
179  }
180 
181  /* NOTE: This function is only used during binary BVH builder, and it
182  * supposed to be configured to have 2 children which will be filled in in a
183  * bit. But this is important to have children reset to NULL. */
185  {
187  visibility = 0;
188  num_children_ = 2;
189  }
190 
191  bool is_leaf() const
192  {
193  return false;
194  }
195  int num_children() const
196  {
197  return num_children_;
198  }
199  BVHNode *get_child(int i) const
200  {
201  assert(i >= 0 && i < num_children_);
202  return children[i];
203  }
204  void print(int depth) const;
205 
208 
209  protected:
211  {
212  for (int i = num_children_; i < kNumMaxChildren; ++i) {
213  children[i] = NULL;
214  }
215  }
216 };
217 
218 class LeafNode : public BVHNode {
219  public:
221  : BVHNode(bounds), lo(lo), hi(hi)
222  {
223  this->bounds = bounds;
224  this->visibility = visibility;
225  }
226 
227  LeafNode(const LeafNode &other) : BVHNode(other), lo(other.lo), hi(other.hi)
228  {
229  }
230 
231  bool is_leaf() const
232  {
233  return true;
234  }
235  int num_children() const
236  {
237  return 0;
238  }
239  BVHNode *get_child(int) const
240  {
241  return NULL;
242  }
243  int num_triangles() const
244  {
245  return hi - lo;
246  }
247  void print(int depth) const;
248 
249  int lo;
250  int hi;
251 };
252 
254 
255 #endif /* __BVH_NODE_H__ */
unsigned int uint
Definition: BLI_sys_types.h:83
BVH_STAT
Definition: bvh_node.h:26
@ BVH_STAT_TRIANGLE_COUNT
Definition: bvh_node.h:30
@ BVH_STAT_NODE_COUNT
Definition: bvh_node.h:27
@ BVH_STAT_CHILDNODE_COUNT
Definition: bvh_node.h:31
@ BVH_STAT_ALIGNED_COUNT
Definition: bvh_node.h:32
@ BVH_STAT_ALIGNED_INNER_COUNT
Definition: bvh_node.h:34
@ BVH_STAT_ALIGNED_LEAF_COUNT
Definition: bvh_node.h:36
@ BVH_STAT_DEPTH
Definition: bvh_node.h:38
@ BVH_STAT_UNALIGNED_COUNT
Definition: bvh_node.h:33
@ BVH_STAT_UNALIGNED_LEAF_COUNT
Definition: bvh_node.h:37
@ BVH_STAT_UNALIGNED_INNER_COUNT
Definition: bvh_node.h:35
@ BVH_STAT_INNER_COUNT
Definition: bvh_node.h:28
@ BVH_STAT_LEAF_COUNT
Definition: bvh_node.h:29
int num_children() const
Definition: bvh_node.h:195
void reset_unused_children()
Definition: bvh_node.h:210
bool is_leaf() const
Definition: bvh_node.h:191
InnerNode(const BoundBox &bounds)
Definition: bvh_node.h:184
InnerNode(const BoundBox &bounds, BVHNode *child0, BVHNode *child1)
Definition: bvh_node.h:149
void print(int depth) const
Definition: bvh_node.cpp:203
int num_children_
Definition: bvh_node.h:206
static constexpr int kNumMaxChildren
Definition: bvh_node.h:147
BVHNode * get_child(int i) const
Definition: bvh_node.h:199
BVHNode * children[kNumMaxChildren]
Definition: bvh_node.h:207
InnerNode(const BoundBox &bounds, BVHNode **children, const int num_children)
Definition: bvh_node.h:165
LeafNode(const LeafNode &other)
Definition: bvh_node.h:227
int num_triangles() const
Definition: bvh_node.h:243
int hi
Definition: bvh_node.h:250
BVHNode * get_child(int) const
Definition: bvh_node.h:239
int lo
Definition: bvh_node.h:249
int num_children() const
Definition: bvh_node.h:235
void print(int depth) const
Definition: bvh_node.cpp:216
bool is_leaf() const
Definition: bvh_node.h:231
LeafNode(const BoundBox &bounds, uint visibility, int lo, int hi)
Definition: bvh_node.h:220
#define CCL_NAMESPACE_END
#define min(a, b)
Definition: sort.c:51
Transform * aligned_space
Definition: bvh_node.h:111
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const
Definition: bvh_node.cpp:29
void update_time()
Definition: bvh_node.cpp:140
uint visibility
Definition: bvh_node.h:104
uint update_visibility()
Definition: bvh_node.cpp:127
virtual int num_children() const =0
float time_to
Definition: bvh_node.h:113
BVHNode(const BoundBox &bounds)
Definition: bvh_node.h:116
float computeSubtreeSAHCost(const BVHParams &p, float probability=1.0f) const
Definition: bvh_node.cpp:114
bool is_unaligned
Definition: bvh_node.h:106
virtual ~BVHNode()
Definition: bvh_node.h:45
virtual bool is_leaf() const =0
void deleteSubtree()
Definition: bvh_node.cpp:105
float time_from
Definition: bvh_node.h:113
void set_aligned_space(const Transform &aligned_space)
Definition: bvh_node.h:59
bool has_unaligned() const
Definition: bvh_node.h:78
virtual BVHNode * get_child(int i) const =0
virtual int num_triangles() const
Definition: bvh_node.h:53
virtual void print(int depth=0) const =0
Transform get_aligned_space() const
Definition: bvh_node.h:70
BVHNode(const BVHNode &other)
Definition: bvh_node.h:126
BoundBox bounds
Definition: bvh_node.h:103
void dump_graph(const char *filename)
Definition: bvh_node.cpp:187
float max
ccl_device_inline Transform transform_identity()
CCL_NAMESPACE_BEGIN struct Transform Transform