9 #ifndef opengl_COctreePointRenderer_H
10 #define opengl_COctreePointRenderer_H
21 namespace global_settings
51 template <
class Derived>
76 return *
static_cast<const Derived*
>(
this);
136 std::numeric_limits<float>::max(),
137 std::numeric_limits<float>::max(),
138 std::numeric_limits<float>::max()),
140 -std::numeric_limits<float>::max(),
141 -std::numeric_limits<float>::max(),
142 -std::numeric_limits<float>::max())
196 switch (my_child_index)
255 throw std::runtime_error(
"my_child_index!=[0,7]");
290 bool corners_are_all_computed =
true,
291 bool trust_me_youre_visible =
false,
292 float approx_area_sqpixels = 0)
const
296 if (!corners_are_all_computed)
298 for (
int i = 0; i < 8; i++)
302 node.getCornerX(i), node.getCornerY(i), node.getCornerZ(i),
303 cr_px[i].
x, cr_px[i].
y, cr_z[i]);
308 std::numeric_limits<float>::max(),
309 std::numeric_limits<float>::max()),
311 -std::numeric_limits<float>::max(),
312 -std::numeric_limits<float>::max());
313 if (!trust_me_youre_visible)
316 for (
int i = 0; i < 8; i++)
324 const bool any_cr_zs_neg =
325 (cr_z[0] < 0 || cr_z[1] < 0 || cr_z[2] < 0 || cr_z[3] < 0 ||
326 cr_z[4] < 0 || cr_z[5] < 0 || cr_z[6] < 0 || cr_z[7] < 0);
327 const bool any_cr_zs_pos =
328 (cr_z[0] > 0 || cr_z[1] > 0 || cr_z[2] > 0 || cr_z[3] > 0 ||
329 cr_z[4] > 0 || cr_z[5] > 0 || cr_z[6] > 0 || cr_z[7] > 0);
330 const bool box_crosses_image_plane = any_cr_zs_pos && any_cr_zs_neg;
337 px_max.
x < 0 || px_max.
y < 0))
344 if (node.all || !node.pts.empty())
350 float render_area_sqpixels =
351 trust_me_youre_visible ? approx_area_sqpixels
352 : std::abs(px_min.x - px_max.
x) *
353 std::abs(px_min.y - px_max.
y);
354 render_area_sqpixels = std::max(1.0f, render_area_sqpixels);
358 TRenderQueueElement(node_idx, render_area_sqpixels));
367 bool children_are_all_visible_for_sure =
true;
369 if (!trust_me_youre_visible)
371 for (
int i = 0; i < 8; i++)
373 if (!(cr_px[i].x >= 0 && cr_px[i].y >= 0 &&
377 children_are_all_visible_for_sure =
false;
384 if (children_are_all_visible_for_sure)
391 const float approx_child_area =
392 trust_me_youre_visible
393 ? approx_area_sqpixels / 8.0f
394 : std::abs(px_min.x - px_max.
x) *
395 std::abs(px_min.y - px_max.
y) / 8.0f;
397 for (
int i = 0; i < 8; i++)
399 node.child_id[i], ri, child_cr_px, child_cr_z,
true,
400 true, approx_child_area);
405 #pragma clang diagnostic push // clang complains about unused vars (becase it
407 #pragma clang diagnostic ignored "-Wunused-variable"
413 node.bb_min.x, node.bb_min.y, node.bb_min.z);
415 node.center.x, node.bb_min.y, node.bb_min.z);
417 node.bb_max.x, node.bb_min.y, node.bb_min.z);
419 node.bb_min.x, node.center.y, node.bb_min.z);
421 node.center.x, node.center.y, node.bb_min.z);
423 node.bb_max.x, node.center.y, node.bb_min.z);
425 node.bb_min.x, node.bb_max.y, node.bb_min.z);
427 node.center.x, node.bb_max.y, node.bb_min.z);
429 node.bb_max.x, node.bb_max.y, node.bb_min.z);
432 node.bb_min.x, node.bb_min.y, node.center.z);
434 node.center.x, node.bb_min.y, node.center.z);
436 node.bb_max.x, node.bb_min.y, node.center.z);
438 node.bb_min.x, node.center.y, node.center.z);
440 node.center.x, node.center.y, node.center.z);
442 node.bb_max.x, node.center.y, node.center.z);
444 node.bb_min.x, node.bb_max.y, node.center.z);
446 node.center.x, node.bb_max.y, node.center.z);
448 node.bb_max.x, node.bb_max.y, node.center.z);
451 node.bb_min.x, node.bb_min.y, node.bb_max.z);
453 node.center.x, node.bb_min.y, node.bb_max.z);
455 node.bb_min.x, node.bb_min.y, node.bb_max.z);
457 node.bb_min.x, node.center.y, node.bb_max.z);
459 node.center.x, node.center.y, node.bb_max.z);
461 node.bb_max.x, node.center.y, node.bb_max.z);
463 node.bb_min.x, node.bb_max.y, node.bb_max.z);
465 node.center.x, node.bb_max.y, node.bb_max.z);
467 node.bb_max.x, node.bb_max.y, node.bb_max.z);
470 #define PROJ_SUB_NODE(POSTFIX) \
471 mrpt::img::TPixelCoordf px_##POSTFIX; \
472 float depth_##POSTFIX; \
473 ri.projectPointPixels( \
474 p_##POSTFIX.x, p_##POSTFIX.y, p_##POSTFIX.z, px_##POSTFIX.x, \
475 px_##POSTFIX.y, depth_##POSTFIX);
477 #define PROJ_SUB_NODE_ALREADY_DONE(INDEX, POSTFIX) \
478 const mrpt::img::TPixelCoordf px_##POSTFIX = cr_px[INDEX]; \
479 float depth_##POSTFIX = cr_z[INDEX];
516 #define DO_RECURSE_CHILD( \
517 INDEX, SEQ0, SEQ1, SEQ2, SEQ3, SEQ4, SEQ5, SEQ6, SEQ7) \
519 mrpt::img::TPixelCoordf child_cr_px[8] = { \
520 px_##SEQ0, px_##SEQ1, px_##SEQ2, px_##SEQ3, \
521 px_##SEQ4, px_##SEQ5, px_##SEQ6, px_##SEQ7}; \
522 float child_cr_z[8] = {depth_##SEQ0, depth_##SEQ1, depth_##SEQ2, \
523 depth_##SEQ3, depth_##SEQ4, depth_##SEQ5, \
524 depth_##SEQ6, depth_##SEQ7}; \
525 this->octree_recursive_render( \
526 node.child_id[INDEX], ri, child_cr_px, child_cr_z); \
532 0, Xm_Ym_Zm, X0_Ym_Zm, Xm_Y0_Zm, X0_Y0_Zm, Xm_Ym_Z0,
533 X0_Ym_Z0, Xm_Y0_Z0, X0_Y0_Z0)
535 1, X0_Ym_Zm, Xp_Ym_Zm, X0_Y0_Zm, Xp_Y0_Zm, X0_Ym_Z0,
536 Xp_Ym_Z0, X0_Y0_Z0, Xp_Y0_Z0)
538 2, Xm_Y0_Zm, X0_Y0_Zm, Xm_Yp_Zm, X0_Yp_Zm, Xm_Y0_Z0,
539 X0_Y0_Z0, Xm_Yp_Z0, X0_Yp_Z0)
541 3, X0_Y0_Zm, Xp_Y0_Zm, X0_Yp_Zm, Xp_Yp_Zm, X0_Y0_Z0,
542 Xp_Y0_Z0, X0_Yp_Z0, Xp_Yp_Z0)
544 4, Xm_Ym_Z0, X0_Ym_Z0, Xm_Y0_Z0, X0_Y0_Z0, Xm_Ym_Zp,
545 X0_Ym_Zp, Xm_Y0_Zp, X0_Y0_Zp)
547 5, X0_Ym_Z0, Xp_Ym_Z0, X0_Y0_Z0, Xp_Y0_Z0, X0_Ym_Zp,
548 Xp_Ym_Zp, X0_Y0_Zp, Xp_Y0_Zp)
550 6, Xm_Y0_Z0, X0_Y0_Z0, Xm_Yp_Z0, X0_Yp_Z0, Xm_Y0_Zp,
551 X0_Y0_Zp, Xm_Yp_Zp, X0_Yp_Zp)
553 7, X0_Y0_Z0, Xp_Y0_Z0, X0_Yp_Z0, Xp_Yp_Z0, X0_Y0_Zp,
554 Xp_Y0_Zp, X0_Yp_Zp, Xp_Yp_Zp)
555 #undef DO_RECURSE_CHILD
557 #undef PROJ_SUB_NODE_ALREADY_DONE
560 #pragma clang diagnostic pop
586 const size_t node_id,
const bool all_pts =
false)
589 const size_t N = all_pts ?
octree_derived().size() : node.pts.size();
600 if (has_to_compute_bb)
603 for (
size_t i = 0; i < N; i++)
606 for (
size_t i = 0; i < N; i++)
617 for (
size_t i = 0; i < N; i++)
621 if (has_to_compute_bb) node.update_bb(p);
624 for (
size_t i = 0; i < N; i++)
628 if (has_to_compute_bb) node.update_bb(p);
632 node.is_leaf =
false;
633 node.center =
mean * (1.0f / N);
638 for (
int i = 0; i < 8; i++)
639 node.child_id[i] = children_idx_base + i;
642 for (
int i = 0; i < 8; i++)
649 for (
size_t j = 0; j < N; j++)
651 const size_t i = all_pts ? j : node.pts[j];
699 std::vector<size_t> emptyVec;
700 node.pts.swap(emptyVec);
705 for (
int i = 0; i < 8; i++)
732 const bool draw_solid_boxes =
false)
const
739 if (!node.is_leaf)
continue;
741 gl_box->setBoxCorners(
744 gl_box->setColor(lines_color);
745 gl_box->setLineWidth(lines_width);
746 gl_box->setWireframe(!draw_solid_boxes);
755 size_t total_elements = 0;
760 o <<
"Node #" << i <<
": ";
771 o << node.pts.size() <<
" elements; ";
772 total_elements += node.pts.size();
777 o <<
"parent, center=(" << node.center.x <<
"," << node.center.y
778 <<
"," << node.center.z <<
"), children: " << node.child_id[0]
779 <<
"," << node.child_id[1] <<
"," << node.child_id[2] <<
","
780 << node.child_id[3] <<
"," << node.child_id[4] <<
","
781 << node.child_id[5] <<
"," << node.child_id[6] <<
","
782 << node.child_id[7] <<
"; ";
784 o <<
" bb: (" << node.bb_min.x <<
"," << node.bb_min.y <<
","
785 << node.bb_min.z <<
")-(" << node.bb_max.x <<
"," << node.bb_max.y
786 <<
"," << node.bb_max.z <<
")\n";
788 o <<
"Total elements in all nodes: " << total_elements << std::endl;