9 #ifndef opengl_COctreePointRenderer_H
10 #define opengl_COctreePointRenderer_H
20 namespace global_settings
44 template <
class Derived>
68 inline const Derived &
octree_derived()
const {
return *
static_cast<const Derived*
>(
this); }
120 bb_min( std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max() ),
121 bb_max(-std::numeric_limits<float>::max(),-std::numeric_limits<float>::max(),-std::numeric_limits<float>::max() )
144 inline float getCornerX(
int i)
const {
return (i & 0x01)==0 ? bb_min.
x : bb_max.
x; }
145 inline float getCornerY(
int i)
const {
return (i & 0x02)==0 ? bb_min.
y : bb_max.
y; }
146 inline float getCornerZ(
int i)
const {
return (i & 0x04)==0 ? bb_min.
z : bb_max.
z; }
151 switch (my_child_index)
191 default:
throw std::runtime_error(
"my_child_index!=[0,7]");
201 inline TRenderQueueElement(
const size_t id,
float area_sq) : node_id(id), render_area_sqpixels(area_sq) { }
221 bool corners_are_all_computed =
true,
222 bool trust_me_youre_visible =
false,
223 float approx_area_sqpixels = 0
228 if (!corners_are_all_computed)
230 for (
int i=0;i<8;i++)
234 node.getCornerX(i),node.getCornerY(i),node.getCornerZ(i),
235 cr_px[i].
x,cr_px[i].
y,cr_z[i]);
239 mrpt::utils::TPixelCoordf px_min( std::numeric_limits<float>::max(),std::numeric_limits<float>::max()), px_max(-std::numeric_limits<float>::max(),-std::numeric_limits<float>::max());
240 if (!trust_me_youre_visible)
243 for (
int i=0;i<8;i++)
249 const bool any_cr_zs_neg = (cr_z[0]<0 ||cr_z[1]<0 ||cr_z[2]<0 ||cr_z[3]<0 ||cr_z[4]<0 ||cr_z[5]<0 ||cr_z[6]<0 ||cr_z[7]<0);
250 const bool any_cr_zs_pos = (cr_z[0]>0 ||cr_z[1]>0 ||cr_z[2]>0 ||cr_z[3]>0 ||cr_z[4]>0 ||cr_z[5]>0 ||cr_z[6]>0 ||cr_z[7]>0);
251 const bool box_crosses_image_plane = any_cr_zs_pos && any_cr_zs_neg;
255 if (!box_crosses_image_plane && ( px_min.x>=ri.
vp_width || px_min.y>=ri.
vp_height || px_max.
x<0 || px_max.
y<0) )
262 if (node.all || !node.pts.empty())
267 const float render_area_sqpixels = trust_me_youre_visible ?
273 m_render_queue.push_back( TRenderQueueElement(node_idx,render_area_sqpixels) );
280 bool children_are_all_visible_for_sure =
true;
282 if (!trust_me_youre_visible)
284 for (
int i=0;i<8;i++)
286 if (!( cr_px[i].x>=0 && cr_px[i].y>=0 && cr_px[i].x<ri.
vp_width && cr_px[i].
y<ri.
vp_height ))
288 children_are_all_visible_for_sure =
false;
295 if (children_are_all_visible_for_sure)
301 const float approx_child_area = trust_me_youre_visible ?
302 approx_area_sqpixels/8.0f
306 for (
int i=0;i<8;i++)
312 #pragma clang diagnostic push // clang complains about unused vars (becase it doesn't realize of the macros?)
313 #pragma clang diagnostic ignored "-Wunused-variable"
348 #define PROJ_SUB_NODE(POSTFIX) \
349 mrpt::utils::TPixelCoordf px_##POSTFIX; \
350 float depth_##POSTFIX; \
351 ri.projectPointPixels( p_##POSTFIX.x, p_##POSTFIX.y, p_##POSTFIX.z, px_##POSTFIX.x,px_##POSTFIX.y,depth_##POSTFIX);
353 #define PROJ_SUB_NODE_ALREADY_DONE(INDEX, POSTFIX) \
354 const mrpt::utils::TPixelCoordf px_##POSTFIX = cr_px[INDEX]; \
355 float depth_##POSTFIX = cr_z[INDEX];
392 #define DO_RECURSE_CHILD(INDEX, SEQ0,SEQ1,SEQ2,SEQ3,SEQ4,SEQ5,SEQ6,SEQ7) \
394 mrpt::utils::TPixelCoordf child_cr_px[8] = { px_##SEQ0,px_##SEQ1,px_##SEQ2,px_##SEQ3,px_##SEQ4,px_##SEQ5,px_##SEQ6,px_##SEQ7 }; \
395 float child_cr_z[8] = { depth_##SEQ0,depth_##SEQ1,depth_##SEQ2,depth_##SEQ3,depth_##SEQ4,depth_##SEQ5,depth_##SEQ6,depth_##SEQ7 }; \
396 this->octree_recursive_render(node.child_id[INDEX],ri,child_cr_px, child_cr_z); \
400 DO_RECURSE_CHILD(0, Xm_Ym_Zm, X0_Ym_Zm, Xm_Y0_Zm, X0_Y0_Zm, Xm_Ym_Z0, X0_Ym_Z0, Xm_Y0_Z0, X0_Y0_Z0 )
401 DO_RECURSE_CHILD(1, X0_Ym_Zm, Xp_Ym_Zm, X0_Y0_Zm, Xp_Y0_Zm, X0_Ym_Z0, Xp_Ym_Z0, X0_Y0_Z0, Xp_Y0_Z0 )
402 DO_RECURSE_CHILD(2, Xm_Y0_Zm, X0_Y0_Zm, Xm_Yp_Zm, X0_Yp_Zm, Xm_Y0_Z0, X0_Y0_Z0, Xm_Yp_Z0, X0_Yp_Z0 )
403 DO_RECURSE_CHILD(3, X0_Y0_Zm, Xp_Y0_Zm, X0_Yp_Zm, Xp_Yp_Zm, X0_Y0_Z0, Xp_Y0_Z0, X0_Yp_Z0, Xp_Yp_Z0 )
404 DO_RECURSE_CHILD(4, Xm_Ym_Z0, X0_Ym_Z0, Xm_Y0_Z0, X0_Y0_Z0, Xm_Ym_Zp, X0_Ym_Zp, Xm_Y0_Zp, X0_Y0_Zp )
405 DO_RECURSE_CHILD(5, X0_Ym_Z0, Xp_Ym_Z0, X0_Y0_Z0, Xp_Y0_Z0, X0_Ym_Zp, Xp_Ym_Zp, X0_Y0_Zp, Xp_Y0_Zp )
406 DO_RECURSE_CHILD(6, Xm_Y0_Z0, X0_Y0_Z0, Xm_Yp_Z0, X0_Yp_Z0, Xm_Y0_Zp, X0_Y0_Zp, Xm_Yp_Zp, X0_Yp_Zp )
407 DO_RECURSE_CHILD(7, X0_Y0_Z0, Xp_Y0_Z0, X0_Yp_Z0, Xp_Yp_Z0, X0_Y0_Zp, Xp_Y0_Zp, X0_Yp_Zp, Xp_Yp_Zp )
408 #undef DO_RECURSE_CHILD
410 #undef PROJ_SUB_NODE_ALREADY_DONE
413 #pragma clang diagnostic pop
438 const size_t N = all_pts ?
octree_derived().size() : node.pts.size();
449 if (has_to_compute_bb)
452 for (
size_t i=0;i<N;i++) node.update_bb(
octree_derived().getPointf(i) );
453 else for (
size_t i=0;i<N;i++) node.update_bb(
octree_derived().getPointf(node.pts[i]) );
462 for (
size_t i=0;i<N;i++)
466 if (has_to_compute_bb) node.update_bb( p );
469 for (
size_t i=0;i<N;i++)
473 if (has_to_compute_bb) node.update_bb( p );
477 node.is_leaf =
false;
478 node.center =
mean * (1.0f/N);
483 for (
int i=0;i<8;i++)
484 node.child_id[i] = children_idx_base + i;
487 for (
int i=0;i<8;i++)
488 m_octree_nodes[children_idx_base + i].setBBFromOrderInParent(node,i);
492 for (
size_t j=0;j<N;j++)
494 const size_t i = all_pts ? j : node.pts[j];
530 std::vector<size_t> emptyVec;
531 node.pts.swap(emptyVec);
535 for (
int i=0;i<8;i++)
556 const double lines_width = 1,
558 const bool draw_solid_boxes =
false )
const
565 if (!node.is_leaf)
continue;
568 gl_box->setColor(lines_color);
569 gl_box->setLineWidth(lines_width);
570 gl_box->setWireframe(!draw_solid_boxes);
580 size_t total_elements = 0;
585 o <<
"Node #" << i <<
": ";
589 if (node.all) { o <<
"(all)\n"; total_elements+=
octree_derived().size(); }
590 else { o << node.pts.size() <<
" elements; "; total_elements+=node.pts.size(); }
595 o <<
"parent, center=(" << node.center.x <<
"," << node.center.y<<
","<<node.center.z<<
"), children: "
596 << node.child_id[0] <<
","<< node.child_id[1] <<
","<< node.child_id[2] <<
","<< node.child_id[3] <<
","
597 << node.child_id[4] <<
","<< node.child_id[5] <<
","<< node.child_id[6] <<
","<< node.child_id[7] <<
"; ";
599 o <<
" bb: (" << node.bb_min.x <<
","<< node.bb_min.y <<
","<< node.bb_min.z <<
")-("
600 << node.bb_max.x <<
","<< node.bb_max.y <<
","<< node.bb_max.z <<
")\n";
602 o <<
"Total elements in all nodes: " << total_elements << std::endl;