28 #define OTD_RAD2DEG 57.2957795 33 m_occupiedThresSize(0), m_freeThresSize(0),
34 m_occupiedSize(0), m_freeSize(0), m_selectionSize(0),
35 octree_grid_vertex_size(0), m_alphaOccupied(0.8), map_id(0)
64 static int gl_list_index = -1;
66 gl_list_index = glGenLists(1);
71 glDeleteLists(gl_list_index,1);
77 std::cout <<
"Preparing batch rendering, please wait ...\n";
78 glNewList(gl_list_index, GL_COMPILE_AND_EXECUTE);
89 glTranslatef(relative_transform.
x(), relative_transform.
y(), relative_transform.
z());
92 float scale = sqrt(q.
x() * q.
x() + q.
y() * q.
y() + q.
z() * q.
z());
94 float axis_x = q.
x() / scale;
95 float axis_y = q.
y() / scale;
96 float axis_z = q.
z() / scale;
98 glRotatef(angle, axis_x, axis_y, axis_z);
101 glEnableClientState(GL_VERTEX_ARRAY);
116 glDisableClientState(GL_VERTEX_ARRAY);
122 std::cout <<
"Finished preparation of batch rendering.\n";
128 glCallList(gl_list_index);
151 bool showAll = (octree.
size() < 5 * 1e6);
152 bool uses_origin = ( (origin.
rot().
x() != 0.) && (origin.
rot().
y() != 0.)
153 && (origin.
rot().
z() != 0.) && (origin.
rot().
u() != 1.) );
158 unsigned int cnt_occupied(0), cnt_occupied_thres(0), cnt_free(0), cnt_free_thres(0);
159 for(OcTree::tree_iterator it = octree.
begin_tree(this->m_max_tree_depth),
160 end=octree.
end_tree(); it!= end; ++it) {
178 double minX, minY, minZ, maxX, maxY, maxZ;
186 std::vector<octomath::Vector3> cube_template;
189 unsigned int idx_occupied(0), idx_occupied_thres(0), idx_free(0), idx_free_thres(0);
190 unsigned int color_idx_occupied(0), color_idx_occupied_thres(0);
194 for(OcTree::tree_iterator it = octree.
begin_tree(this->m_max_tree_depth),
195 end=octree.
end_tree(); it!= end; ++it) {
251 unsigned int& glArraySize,
252 GLfloat*** glArray, GLfloat** glColorArray) {
254 clearCubes(glArray, glArraySize, glColorArray);
257 glArraySize = num_cubes * 4 * 3;
260 *glArray =
new GLfloat* [6];
261 for (
unsigned i = 0; i<6; ++i){
262 (*glArray)[i] =
new GLfloat[glArraySize];
265 if (glColorArray != NULL)
266 *glColorArray =
new GLfloat[glArraySize * 4 *4];
270 std::vector<octomath::Vector3>& cube_template) {
271 cube_template.clear();
272 cube_template.reserve(24);
304 const std::vector<octomath::Vector3>& cube_template,
305 const unsigned int& current_array_idx,
306 GLfloat*** glArray) {
314 double half_cube_size = GLfloat(v.second /2.0 -eps);
315 unsigned int i = current_array_idx;
320 p = v.first + cube_template[0] * half_cube_size;
321 (*glArray)[0][i] = p.
x();
322 (*glArray)[0][i+1] = p.
y();
323 (*glArray)[0][i+2] = p.
z();
325 p = v.first + cube_template[1] * half_cube_size;
326 (*glArray)[1][i] = p.
x();
327 (*glArray)[1][i+1] = p.
y();
328 (*glArray)[1][i+2] = p.
z();
330 p = v.first + cube_template[2] * half_cube_size;
331 (*glArray)[2][i] = p.
x();
332 (*glArray)[2][i+1] = p.
y();
333 (*glArray)[2][i+2] = p.
z();
335 p = v.first + cube_template[3] * half_cube_size;
336 (*glArray)[3][i] = p.
x();
337 (*glArray)[3][i+1] = p.
y();
338 (*glArray)[3][i+2] = p.
z();
340 p = v.first + cube_template[4] * half_cube_size;
341 (*glArray)[4][i] = p.
x();
342 (*glArray)[4][i+1] = p.
y();
343 (*glArray)[4][i+2] = p.
z();
345 p = v.first + cube_template[5] * half_cube_size;
346 (*glArray)[5][i] = p.
x();
347 (*glArray)[5][i+1] = p.
y();
348 (*glArray)[5][i+2] = p.
z();
351 p = v.first + cube_template[6] * half_cube_size;
352 (*glArray)[0][i] = p.
x();
353 (*glArray)[0][i+1] = p.
y();
354 (*glArray)[0][i+2] = p.
z();
356 p = v.first + cube_template[7] * half_cube_size;
357 (*glArray)[1][i] = p.
x();
358 (*glArray)[1][i+1] = p.
y();
359 (*glArray)[1][i+2] = p.
z();
361 p = v.first + cube_template[8] * half_cube_size;
362 (*glArray)[2][i] = p.
x();
363 (*glArray)[2][i+1] = p.
y();
364 (*glArray)[2][i+2] = p.
z();
366 p = v.first + cube_template[9] * half_cube_size;
367 (*glArray)[3][i] = p.
x();
368 (*glArray)[3][i+1] = p.
y();
369 (*glArray)[3][i+2] = p.
z();
371 p = v.first + cube_template[10] * half_cube_size;
372 (*glArray)[4][i] = p.
x();
373 (*glArray)[4][i+1] = p.
y();
374 (*glArray)[4][i+2] = p.
z();
376 p = v.first + cube_template[11] * half_cube_size;
377 (*glArray)[5][i] = p.
x();
378 (*glArray)[5][i+1] = p.
y();
379 (*glArray)[5][i+2] = p.
z();
382 p = v.first + cube_template[12] * half_cube_size;
383 (*glArray)[0][i] = p.
x();
384 (*glArray)[0][i+1] = p.
y();
385 (*glArray)[0][i+2] = p.
z();
387 p = v.first + cube_template[13] * half_cube_size;
388 (*glArray)[1][i] = p.
x();
389 (*glArray)[1][i+1] = p.
y();
390 (*glArray)[1][i+2] = p.
z();
392 p = v.first + cube_template[14] * half_cube_size;
393 (*glArray)[2][i] = p.
x();
394 (*glArray)[2][i+1] = p.
y();
395 (*glArray)[2][i+2] = p.
z();
397 p = v.first + cube_template[15] * half_cube_size;
398 (*glArray)[3][i] = p.
x();
399 (*glArray)[3][i+1] = p.
y();
400 (*glArray)[3][i+2] = p.
z();
402 p = v.first + cube_template[16] * half_cube_size;
403 (*glArray)[4][i] = p.
x();
404 (*glArray)[4][i+1] = p.
y();
405 (*glArray)[4][i+2] = p.
z();
407 p = v.first + cube_template[17] * half_cube_size;
408 (*glArray)[5][i] = p.
x();
409 (*glArray)[5][i+1] = p.
y();
410 (*glArray)[5][i+2] = p.
z();
413 p = v.first + cube_template[18] * half_cube_size;
414 (*glArray)[0][i] = p.
x();
415 (*glArray)[0][i+1] = p.
y();
416 (*glArray)[0][i+2] = p.
z();
418 p = v.first + cube_template[19] * half_cube_size;
419 (*glArray)[1][i] = p.
x();
420 (*glArray)[1][i+1] = p.
y();
421 (*glArray)[1][i+2] = p.
z();
423 p = v.first + cube_template[20] * half_cube_size;
424 (*glArray)[2][i] = p.
x();
425 (*glArray)[2][i+1] = p.
y();
426 (*glArray)[2][i+2] = p.
z();
428 p = v.first + cube_template[21] * half_cube_size;
429 (*glArray)[3][i] = p.
x();
430 (*glArray)[3][i+1] = p.
y();
431 (*glArray)[3][i+2] = p.
z();
433 p = v.first + cube_template[22] * half_cube_size;
434 (*glArray)[4][i] = p.
x();
435 (*glArray)[4][i+1] = p.
y();
436 (*glArray)[4][i+2] = p.
z();
438 p = v.first + cube_template[23] * half_cube_size;
439 (*glArray)[5][i] = p.
x();
440 (*glArray)[5][i+1] = p.
y();
441 (*glArray)[5][i+2] = p.
z();
449 const unsigned int& current_array_idx,
450 GLfloat** glColorArray) {
452 if (glColorArray == NULL)
return current_array_idx;
454 unsigned int colorIdx = current_array_idx;
456 for (
int k = 0; k < 4; ++k) {
469 const unsigned char& g,
470 const unsigned char& b,
471 const unsigned char& a,
472 const unsigned int& current_array_idx,
473 GLfloat** glColorArray) {
475 if (glColorArray == NULL)
return current_array_idx;
476 unsigned int colorIdx = current_array_idx;
478 for (
int k = 0; k < 4; ++k) {
479 (*glColorArray)[colorIdx ] = (double) r/255.;
480 (*glColorArray)[colorIdx + 1] = (double) g/255.;
481 (*glColorArray)[colorIdx + 2] = (double) b/255.;
482 (*glColorArray)[colorIdx + 3] = (double) a/255.;
490 unsigned int& glArraySize,
491 GLfloat** glColorArray) {
492 if (glArraySize != 0) {
493 for (
unsigned i = 0; i < 6; ++i) {
494 delete[] (*glArray)[i];
500 if (glColorArray != NULL && *glColorArray != NULL) {
501 delete[] *glColorArray;
502 *glColorArray = NULL;
509 GLfloat*** glArray,
unsigned int& glArraySize,
511 GLfloat** glColorArray) {
513 unsigned int colorIdx = 0;
515 std::vector<octomath::Vector3> cube_template;
518 for (std::list<octomap::OcTreeVolume>::const_iterator it=voxels.begin();
519 it != voxels.end(); it++) {
523 if (glColorArray != NULL) {
524 for (std::list<octomap::OcTreeVolume>::const_iterator it=voxels.begin();
525 it != voxels.end(); it++) {
541 std::list<octomap::OcTreeVolume>::iterator it_rec;
546 x = it_rec->first.x();
547 y = it_rec->first.y();
548 z = it_rec->first.z();
550 double half_voxel_size = it_rec->second / 2.0;
680 glColor3f(0.784f, 0.66f, 0);
682 else if (this->
map_id == 1) {
683 glColor3f(0.68f, 0., 0.62f);
686 glColor3f(0., 0.784f, 0.725f);
694 glColor3f(0.6f, 0.6f, 0.6f);
697 glColor3f(0.1f, 0.1f, 0.1f);
720 glColor3f(0.5f, 0.5f, 0.5f);
723 glColor3f(0.9f, 0.9f, 0.9f);
742 glColor4f(1.0, 0.0, 0.0, 0.5);
748 GLfloat* cubeColorArray)
const {
749 if (cubeArraySize == 0 || cubeArray == NULL){
750 std::cerr <<
"Warning: GLfloat array to draw cubes appears to be empty, nothing drawn.\n";
755 GLfloat* curcol =
new GLfloat[4];
756 glGetFloatv(GL_CURRENT_COLOR, curcol);
761 glEnableClientState(GL_COLOR_ARRAY);
762 glColorPointer(4, GL_FLOAT, 0, cubeColorArray);
766 glNormal3f(0.0f, 1.0f, 0.0f);
767 glVertexPointer(3, GL_FLOAT, 0, cubeArray[0]);
768 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
770 glNormal3f(0.0f, -1.0f, 0.0f);
771 glVertexPointer(3, GL_FLOAT, 0, cubeArray[1]);
772 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
774 glNormal3f(1.0f, 0.0f, 0.0f);
775 glVertexPointer(3, GL_FLOAT, 0, cubeArray[2]);
776 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
778 glNormal3f(-1.0f, 0.0f, 0.0f);
779 glVertexPointer(3, GL_FLOAT, 0, cubeArray[3]);
780 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
782 glNormal3f(0.0f, 0.0f, -1.0f);
783 glVertexPointer(3, GL_FLOAT, 0, cubeArray[4]);
784 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
786 glNormal3f(0.0f, 0.0f, 1.0f);
787 glVertexPointer(3, GL_FLOAT, 0, cubeArray[5]);
788 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
791 && (cubeColorArray != NULL)){
792 glDisableClientState(GL_COLOR_ARRAY);
797 glDisable(GL_LIGHTING);
798 glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);
799 glEnable (GL_LINE_SMOOTH);
800 glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
802 glColor3f(0.0f, 0.0f, 0.0f);
803 glCullFace(GL_FRONT_AND_BACK);
807 glNormal3f(0.0f, 1.0f, 0.0f);
808 glVertexPointer(3, GL_FLOAT, 0, cubeArray[0]);
809 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
811 glNormal3f(0.0f, -1.0f, 0.0f);
812 glVertexPointer(3, GL_FLOAT, 0, cubeArray[1]);
813 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
815 glNormal3f(1.0f, 0.0f, 0.0f);
816 glVertexPointer(3, GL_FLOAT, 0, cubeArray[2]);
817 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
819 glNormal3f(-1.0f, 0.0f, 0.0f);
820 glVertexPointer(3, GL_FLOAT, 0, cubeArray[3]);
821 glDrawArrays(GL_QUADS, 0, cubeArraySize / 3);
826 glDisable(GL_LINE_SMOOTH);
827 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
828 glEnable(GL_LIGHTING);
839 glDisable(GL_LIGHTING);
840 glEnable(GL_LINE_SMOOTH);
844 glColor3f(0.0, 0.0, 0.0);
847 glDisable(GL_LINE_SMOOTH);
848 glEnable(GL_LIGHTING);
862 std::cout <<
"OcTreeDrawer: setting new global origin: " << t << std::endl;
866 std::cout <<
"origin : " <<
origin << std::endl;
868 std::cout <<
"relative trans: " << relative_transform << std::endl;
877 float length = 0.15f;
879 GLboolean lighting, colorMaterial;
880 glGetBooleanv(GL_LIGHTING, &lighting);
881 glGetBooleanv(GL_COLOR_MATERIAL, &colorMaterial);
883 glDisable(GL_COLOR_MATERIAL);
893 if (angle > 0) glRotatef(
OTD_RAD2DEG*angle, ax, ay, az);
896 color[0] = 0.7f; color[1] = 0.7f; color[2] = 1.0f; color[3] = 1.0f;
897 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
900 color[0] = 1.0f; color[1] = 0.7f; color[2] = 0.7f; color[3] = 1.0f;
901 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
903 glRotatef(90.0, 0.0, 1.0, 0.0);
907 color[0] = 0.7f; color[1] = 1.0f; color[2] = 0.7f; color[3] = 1.0f;
908 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color);
910 glRotatef(-90.0, 1.0, 0.0, 0.0);
914 glTranslatef(relative_transform.
trans().
x(), relative_transform.
trans().
y(), relative_transform.
trans().
z());
917 glEnable(GL_COLOR_MATERIAL);
919 glDisable(GL_LIGHTING);
tree_iterator begin_tree(unsigned char maxDepth=0) const
const tree_iterator end_tree() const
bool isNodeAtThreshold(const OcTreeNode *occupancyNode) const
bool m_alternativeDrawing
void setOcTree(const AbstractOcTree &octree)
sets a new OcTree that should be drawn by this drawer
unsigned int setCubeColorHeightmap(const octomap::OcTreeVolume &v, const unsigned int ¤t_array_idx, GLfloat **glColorArray)
unsigned int octree_grid_vertex_size
void drawFreeVoxels() const
void clearCubes(GLfloat ***glArray, unsigned int &glArraySize, GLfloat **glColorArray=NULL)
clear OpenGL visualization
GLfloat ** m_occupiedArray
GLfloat * octree_grid_vertex_array
OpenGL representation of Octree (grid structure)
void heightMapGray(double h, GLfloat *glArrayPos) const
void clearOcTreeSelection()
clear the visualization of the OcTree selection
void drawOccupiedVoxels() const
void clearOcTreeStructure()
std::pair< point3d, double > OcTreeVolume
octomap::pose6d initial_origin
GLfloat * m_occupiedColorArray
void enableOcTree(bool enabled=true)
void initCubeTemplate(const octomath::Pose6D &origin, std::vector< octomath::Vector3 > &cube_template)
setup cube template
void drawSelection() const
void setOcTreeSelection(const std::list< octomap::OcTreeVolume > &selectedPoints)
sets a new selection of the current OcTree to be drawn
void drawOctreeGrid() const
virtual void getMetricMin(double &x, double &y, double &z)
void generateCubes(const std::list< octomap::OcTreeVolume > &voxels, GLfloat ***glArray, unsigned int &glArraySize, octomath::Pose6D &origin, GLfloat **glColorArray=NULL)
GLfloat ** m_freeThresArray
bool m_octree_grid_vis_initialized
GLfloat ** m_occupiedThresArray
OpenGL representation of Octree cells (cubes)
unsigned int m_selectionSize
unsigned int generateCube(const octomap::OcTreeVolume &v, const std::vector< octomath::Vector3 > &cube_template, const unsigned int ¤t_array_idx, GLfloat ***glArray)
add one cube to arrays
virtual void getMetricMax(double &x, double &y, double &z)
void initGLArrays(const unsigned int &num_cubes, unsigned int &glArraySize, GLfloat ***glArray, GLfloat **glColorArray)
setup OpenGL arrays
std::list< octomap::OcTreeVolume > m_grid_voxels
Vector3 rotate(const Vector3 &v) const
unsigned int m_occupiedThresSize
void setAlphaOccupied(double alpha)
sets alpha level for occupied cells
virtual size_t size() const
unsigned int m_occupiedSize
unsigned int setCubeColorRGBA(const unsigned char &r, const unsigned char &g, const unsigned char &b, const unsigned char &a, const unsigned int ¤t_array_idx, GLfloat **glColorArray)
GLfloat ** m_selectionArray
bool isNodeOccupied(const OcTreeNode *occupancyNode) const
GLfloat * m_occupiedThresColorArray
Color array for occupied cells (height)
void setOrigin(octomap::pose6d t)
void drawCubes(GLfloat **cubeArray, unsigned int cubeArraySize, GLfloat *cubeColorArray=NULL) const
void heightMapColor(double h, GLfloat *glArrayPos) const
unsigned int m_freeThresSize
static void drawArrow(qreal length=1.0, qreal radius=-1.0, int nbSubdivisions=12)