39 : m_entities( entities ),
43 bool operator() (
int lhs,
int rhs)
const 45 const Bbox3f& left = m_entities[lhs].m_bbox;
46 const Bbox3f& right = m_entities[rhs].m_bbox;
47 const float leftval = left.
m_min[m_dim] + left.
m_max[m_dim];
48 const float rightval = right.
m_min[m_dim] + right.
m_max[m_dim];
49 return leftval < rightval;
53 const std::vector<Entity>& m_entities;
58 const uint32 n_entities,
62 std::vector<bvh_node_type>& nodes = bvh->m_nodes;
65 m_tag_bits.resize( n_entities,
false );
68 m_tmpInt.resize( n_entities );
70 m_indices[0].resize( n_entities );
71 for(uint32 i = 0; i < n_entities; ++i)
72 m_indices[0][i] = static_cast<int>( i );
74 for(
int dim = 1; dim < 3; ++dim)
75 m_indices[dim] = m_indices[0];
81 std::sort( m_indices[0].
begin(), m_indices[0].end(), pred_x );
82 std::sort( m_indices[1].
begin(), m_indices[1].end(), pred_y );
83 std::sort( m_indices[2].
begin(), m_indices[2].end(), pred_z );
87 compute_bbox( 0u, n_entities, root_bbox );
89 Node_stack node_stack;
92 node.m_bbox = root_bbox;
94 node.m_end = n_entities;
98 node_stack.push( node );
102 stats->m_max_depth = 0u;
105 nodes.erase( nodes.begin(), nodes.end() );
106 nodes.push_back( root );
107 bvh->m_bboxes.resize( 1u );
108 bvh->m_bboxes[0] = root_bbox;
110 while (node_stack.empty() ==
false)
112 const Node node = node_stack.top();
115 const uint32 node_index = node.m_node;
119 bvh->m_bboxes[ node_index ] = bbox;
122 stats->m_max_depth = std::max( stats->m_max_depth, node.m_depth );
124 if (node.m_end - node.m_begin <= m_max_leaf_size)
141 if (find_best_split( node, middle, l_bb, r_bb ) ==
false)
143 if (m_force_splitting)
145 middle = (node.m_begin + node.m_end) / 2;
146 compute_bbox( node.m_begin, middle, l_bb );
147 compute_bbox( middle, node.m_end, r_bb );
159 const uint32 left_node_index = uint32( nodes.size() );
160 nodes.resize( left_node_index + 2 );
161 bvh->m_bboxes.resize( left_node_index + 2 );
168 right_node.m_bbox = r_bb;
169 right_node.m_begin = middle;
170 right_node.m_end = node.m_end;
171 right_node.m_depth = node.m_depth + 1u;
172 right_node.m_node = left_node_index + 1u;
173 node_stack.push( right_node );
176 left_node.m_bbox = l_bb;
177 left_node.m_begin = node.m_begin;
178 left_node.m_end = middle;
179 left_node.m_depth = node.m_depth + 1u;
180 left_node.m_node = left_node_index;
181 node_stack.push( left_node );
186 template <
typename Iterator>
188 const Iterator
begin,
193 const uint32 n_entities = uint32( end - begin );
195 m_entities.resize( n_entities );
197 for (Iterator it = begin; it != end; ++it)
199 m_entities[i].m_bbox = *it;
200 m_entities[i].m_index = i;
201 m_entities[i].m_cost = 1.0f;
206 build( n_entities, bvh, stats );
215 template <
typename Iterator,
typename CostIterator>
219 CostIterator cost_begin,
223 const uint32 n_entities = uint32( end - begin );
225 m_entities.resize( n_entities );
227 for (Iterator it = begin; it != end; ++it)
229 m_entities[i].m_bbox = *it;
230 m_entities[i].m_index = i;
231 m_entities[i].m_cost = cost_begin[i];
236 build( n_entities, bvh, stats );
245 bool operator() (
const Entity& lhs,
const Entity& rhs)
const 247 const float leftval = lhs.m_bbox[0][m_dim] + lhs.m_bbox[1][m_dim];
248 const float rightval = rhs.m_bbox[0][m_dim] + rhs.m_bbox[1][m_dim];
250 if (leftval == rightval)
251 return lhs.m_index < rhs.m_index;
253 return leftval < rightval;
260 inline float Bvh_sah_builder::area(
const Bbox3f& bbox)
262 const Vector3f edge = bbox[1] - bbox[0];
263 return edge[0] * edge[1] + edge[2] * (edge[0] + edge[1]);
266 inline bool Bvh_sah_builder::find_largest_axis_split(
272 const uint32
begin = node.m_begin;
273 const uint32 end = node.m_end;
274 const uint32 n_entities = end -
begin;
275 if (m_bboxes.size() < n_entities+1)
276 m_bboxes.resize( n_entities+1 );
277 if (m_costs.size() < n_entities+1)
278 m_costs.resize( n_entities+1 );
280 float min_cost = std::numeric_limits<float>::max();
283 const vector_type edge = node.m_bbox[1] - node.m_bbox[0];
284 const int dim = max_element( edge );
291 std::vector<int>& indices = m_indices[dim];
294 for(uint32 i = 1; i <= n_entities; ++i)
295 m_bboxes[i] =
bbox_type( m_bboxes[i-1], m_entities[ indices[ end - i ] ].m_bbox );
297 for(uint32 i = 1; i <= n_entities; ++i)
298 m_costs[i] = m_costs[i-1] + m_entities[ indices[ end - i ] ].m_cost;
304 for(uint32 num_left = 1; num_left < n_entities; ++num_left)
306 const int num_right = n_entities - num_left;
308 rbb = m_bboxes[num_right];
309 lbb.
insert( m_entities[ indices[ begin + num_left - 1 ] ].m_bbox );
311 rc = m_costs[num_right];
312 lc += m_entities[ indices[ begin + num_left - 1 ] ].m_cost;
314 if (m_force_alignment && (num_left % m_max_leaf_size != 0))
317 const float sa_left =
area( lbb );
318 const float sa_right =
area( rbb );
320 const float cost = sa_left*lc + sa_right*rc;
326 pivot = begin + num_left;
336 const float curr_cost =
area( node.m_bbox ) * n_entities;
339 if (m_force_splitting ==
false && curr_cost * 1.5f < min_cost )
343 const int* indices_ptr = &m_indices[min_dim][0];
344 for (uint32 i = begin; i < pivot; ++i)
345 m_tag_bits[indices_ptr[i]] =
false;
346 for (uint32 i = pivot; i < end; ++i)
347 m_tag_bits[indices_ptr[i]] =
true;
350 for (
int d = 1; d <= 2; ++d)
352 const int dim = (min_dim+d) % 3;
354 int rightpos = pivot;
356 const int* indices_ptr = &m_indices[dim][0];
357 for (uint32 i = begin; i < end; ++i)
359 const int index = indices_ptr[i];
361 if (m_tag_bits[index])
362 m_tmpInt[rightpos++] =
index;
364 m_tmpInt[leftpos++] =
index;
368 memcpy( &m_indices[dim][begin], &m_tmpInt[begin],
sizeof(
int)*n_entities );
373 inline bool Bvh_sah_builder::find_best_split(
379 const uint32
begin = node.m_begin;
380 const uint32 end = node.m_end;
381 const uint32 n_entities = end -
begin;
383 if (n_entities > m_single_axis_threshold)
384 return find_largest_axis_split( node, pivot, left_bb, right_bb );
386 if (m_bboxes.size() < n_entities+1)
387 m_bboxes.resize( n_entities+1 );
388 if (m_costs.size() < n_entities+1)
389 m_costs.resize( n_entities+1 );
391 float min_cost = std::numeric_limits<float>::max();
395 for(
int dim = 0; dim < 3; ++dim)
402 std::vector<int>& indices = m_indices[dim];
405 for(uint32 i = 1; i <= n_entities; ++i)
406 m_bboxes[i] =
bbox_type( m_bboxes[i-1], m_entities[ indices[ end - i ] ].m_bbox );
408 for(uint32 i = 1; i <= n_entities; ++i)
409 m_costs[i] = m_costs[i-1] + m_entities[ indices[ end - i ] ].m_cost;
415 for(uint32 num_left = 1; num_left < n_entities; ++num_left)
417 const int num_right = n_entities - num_left;
419 rbb = m_bboxes[num_right];
420 lbb.
insert( m_entities[ indices[ begin + num_left - 1 ] ].m_bbox );
422 rc = m_costs[num_right];
423 lc += m_entities[ indices[ begin + num_left - 1 ] ].m_cost;
425 if (m_force_alignment && (num_left % m_max_leaf_size != 0))
428 const float sa_left =
area( lbb );
429 const float sa_right =
area( rbb );
431 const float cost = sa_left*lc + sa_right*rc;
437 pivot = begin + num_left;
448 const float curr_cost =
area( node.m_bbox ) * n_entities;
451 if (m_force_splitting ==
false && curr_cost * 1.5f < min_cost )
455 const int* indices_ptr = &m_indices[min_dim][0];
456 for (uint32 i = begin; i < pivot; ++i)
457 m_tag_bits[indices_ptr[i]] =
false;
458 for (uint32 i = pivot; i < end; ++i)
459 m_tag_bits[indices_ptr[i]] =
true;
462 for (
int d = 1; d <= 2; ++d)
464 const int dim = (min_dim+d) % 3;
466 int rightpos = pivot;
468 const int* indices_ptr = &m_indices[dim][0];
469 for (uint32 i = begin; i < end; ++i)
471 const int index = indices_ptr[i];
473 if (m_tag_bits[index])
474 m_tmpInt[rightpos++] =
index;
476 m_tmpInt[leftpos++] =
index;
480 memcpy( &m_indices[dim][begin], &m_tmpInt[begin],
sizeof(
int)*n_entities );
485 inline void Bvh_sah_builder::compute_bbox(
491 for (uint32 i = begin; i < end; i++)
492 bbox.
insert( m_entities[m_indices[0][i]].m_bbox );
495 namespace deprecated {
497 template <
typename Iterator>
499 const Iterator begin,
503 m_entities.resize( end - begin );
505 for (Iterator it = begin; it != end; ++it)
507 m_entities[i].m_bbox = *it;
508 m_entities[i].m_index = i;
514 Node_stack node_stack;
517 compute_bbox( 0u, uint32(end - begin), node.m_bbox );
519 node.m_end = uint32(end - begin);
523 node_stack.push( node );
527 root.set_type( Bvh_node::kLeaf );
528 root.set_index( 0u );
529 bvh->m_nodes.push_back( root );
530 bvh->m_bboxes.resize( 1u );
532 while (node_stack.empty() ==
false)
534 const Node node = node_stack.top();
537 const uint32 node_index = node.m_node;
540 bvh->m_bboxes[ node_index ] = bbox;
542 if (node.m_end - node.m_begin < m_max_leaf_size)
547 Bvh_node& bvh_node = bvh->m_nodes[ node_index ];
548 bvh_node =
Bvh_node( Bvh_node::kLeaf, node.m_begin, node.m_end );
559 if (find_best_split( node, middle, l_bb, r_bb ) ==
false)
562 Bvh_node& bvh_node = bvh->m_nodes[ node_index ];
563 bvh_node =
Bvh_node( Bvh_node::kLeaf, node.m_begin, node.m_end );
568 const uint32 left_node_index = uint32( bvh->m_nodes.size() );
569 bvh->m_nodes.resize( left_node_index + 2 );
570 bvh->m_bboxes.resize( left_node_index + 2 );
572 Bvh_node& bvh_node = bvh->m_nodes[ node_index ];
573 bvh_node =
Bvh_node( Bvh_node::kInternal, left_node_index, node.m_end - node.m_begin );
577 right_node.m_bbox = r_bb;
578 right_node.m_begin = middle;
579 right_node.m_end = node.m_end;
580 right_node.m_depth = node.m_depth + 1u;
581 right_node.m_node = left_node_index + 1u;
582 node_stack.push( right_node );
585 left_node.m_bbox = l_bb;
586 left_node.m_begin = node.m_begin;
587 left_node.m_end = middle;
588 left_node.m_depth = node.m_depth + 1u;
589 left_node.m_node = left_node_index;
590 node_stack.push( left_node );
602 bool operator() (
const Entity& lhs,
const Entity& rhs)
const 604 const float leftval = lhs.m_bbox[0][m_dim] + lhs.m_bbox[1][m_dim];
605 const float rightval = rhs.m_bbox[0][m_dim] + rhs.m_bbox[1][m_dim];
607 return leftval < rightval;
614 inline float Bvh_sah_builder::area(
const Bbox3f& bbox)
616 const Vector3f edge = bbox[1] - bbox[0];
617 return edge[0] * edge[1] + edge[2] * (edge[0] + edge[1]);
620 inline bool Bvh_sah_builder::find_best_split(
626 float min_cost = std::numeric_limits<float>::max();
629 const uint32 begin = node.m_begin;
630 const uint32 end = node.m_end;
631 const uint32 n_entities = end -
begin;
632 if (m_bboxes.size() < n_entities+1)
633 m_bboxes.resize( n_entities+1 );
636 for(
int dim = 0; dim < 3; ++dim)
642 &m_entities[0] + begin,
643 &m_entities[0] + end,
649 for(uint32 i = 1; i <= n_entities; ++i)
651 m_bboxes[i] = m_bboxes[i-1];
652 m_bboxes[i].insert( m_entities[ end - i ].m_bbox );
658 for(uint32 num_left = 1; num_left < n_entities; ++num_left)
660 const int num_right = n_entities - num_left;
662 rbb = m_bboxes[num_right];
663 lbb.
insert( m_entities[ begin + num_left - 1 ].m_bbox );
665 const float sa_left =
area( lbb );
666 const float sa_right =
area( rbb );
668 const float cost = sa_left*num_left + sa_right*num_right;
674 pivot = begin + num_left;
682 const float curr_cost =
area( node.m_bbox ) * n_entities;
685 if( curr_cost * 1.5f < min_cost)
693 &m_entities[0] + begin,
694 &m_entities[0] + end,
700 inline void Bvh_sah_builder::compute_bbox(
706 for (uint32 i = begin; i < end; i++)
707 bbox.
insert( m_entities[i].m_bbox );
Vector_t m_max
max corner
Definition: bbox.h:126
CUGAR_HOST CUGAR_DEVICE void clear()
Definition: bbox_inline.h:85
thrust::device_vector< T >::iterator begin(thrust::device_vector< T > &vec)
Definition: thrust_view.h:89
Definition: bvh_node.h:45
Vector_t m_min
min corner
Definition: bbox.h:125
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
Definition: bvh_sah_builder.h:51
void build(Iterator begin, Iterator end, bvh_type *bvh, Stats *stats=NULL)
Definition: bvh_sah_builder_inline.h:187
CUGAR_HOST_DEVICE float area(const Bbox2f &bbox)
Definition: bbox_inline.h:134
Definition: bvh_sah_builder_inline.h:35
Definition: bvh_sah_builder_inline.h:240
Definition: bvh_sah_builder_inline.h:597
CUGAR_HOST CUGAR_DEVICE void insert(const Vector_t &v)
Definition: bbox_inline.h:65
uint32 index(const uint32 i) const
remapped point index
Definition: bvh_sah_builder.h:105