scene.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014 Google Inc. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <tango-gl/conversions.h>
19 #include <tango-gl/util.h>
20 
22 #include <rtabmap/utilite/UStl.h>
23 #include <rtabmap/utilite/UTimer.h>
27 #include <pcl/common/transforms.h>
28 #include <pcl/common/common.h>
29 
30 #include <glm/gtx/transform.hpp>
31 
32 #include "scene.h"
33 #include "util.h"
34 
35 // We want to represent the device properly with respect to the ground so we'll
36 // add an offset in z to our origin. We'll set this offset to 1.3 meters based
37 // on the average height of a human standing with a Tango device. This allows us
38 // to place a grid roughly on the ground for most users.
39 const glm::vec3 kHeightOffset = glm::vec3(0.0f, -1.3f, 0.0f);
40 
41 // Color of the motion tracking trajectory.
42 const tango_gl::Color kTraceColor(0.66f, 0.66f, 0.66f);
43 
44 // Color of the ground grid.
45 const tango_gl::Color kGridColor(0.85f, 0.85f, 0.85f);
46 
47 // Frustum scale.
48 const glm::vec3 kFrustumScale = glm::vec3(0.4f, 0.3f, 0.5f);
49 
50 const std::string kGraphVertexShader =
51  "precision mediump float;\n"
52  "precision mediump int;\n"
53  "attribute vec3 vertex;\n"
54  "uniform vec3 color;\n"
55  "uniform mat4 mvp;\n"
56  "varying vec3 v_color;\n"
57  "void main() {\n"
58  " gl_Position = mvp*vec4(vertex.x, vertex.y, vertex.z, 1.0);\n"
59  " v_color = color;\n"
60  "}\n";
61 const std::string kGraphFragmentShader =
62  "precision mediump float;\n"
63  "precision mediump int;\n"
64  "varying vec3 v_color;\n"
65  "void main() {\n"
66  " gl_FragColor = vec4(v_color.z, v_color.y, v_color.x, 1.0);\n"
67  "}\n";
68 
69 
70 
72  background_renderer_(0),
73  gesture_camera_(0),
74  axis_(0),
75  frustum_(0),
76  grid_(0),
77  box_(0),
78  trace_(0),
79  graph_(0),
80  graphVisible_(true),
81  gridVisible_(true),
82  traceVisible_(true),
83  frustumVisible_(true),
84  color_camera_to_display_rotation_(rtabmap::ROTATION_0),
85  currentPose_(0),
86  graph_shader_program_(0),
87  blending_(true),
88  mapRendering_(true),
89  meshRendering_(true),
90  meshRenderingTexture_(true),
91  pointSize_(5.0f),
92  boundingBoxRendering_(false),
93  lighting_(false),
94  backfaceCulling_(true),
95  wireFrame_(false),
96  r_(0.0f),
97  g_(0.0f),
98  b_(0.0f),
99  fboId_(0),
100  depthTexture_(0),
101  screenWidth_(0),
102  screenHeight_(0),
103  doubleTapOn_(false)
104 {
108 }
109 
111  DeleteResources();
112  delete gesture_camera_;
113  delete currentPose_;
114 }
115 
116 //Should only be called in OpenGL thread!
118 {
119  if(axis_ != 0)
120  {
121  DeleteResources();
122  }
123 
124  UASSERT(axis_ == 0);
125 
126 
127  axis_ = new tango_gl::Axis();
128  frustum_ = new tango_gl::Frustum();
129  trace_ = new tango_gl::Trace();
130  grid_ = new tango_gl::Grid();
131  box_ = new BoundingBoxDrawable();
132 
133 
134  axis_->SetScale(glm::vec3(0.5f,0.5f,0.5f));
139  grid_->SetPosition(kHeightOffset);
140  box_->SetShader();
141  box_->SetColor(1,0,0);
142 
144 
145  if(graph_shader_program_ == 0)
146  {
149  }
150 }
151 
152 //Should only be called in OpenGL thread!
154 
155  LOGI("Scene::DeleteResources()");
156  if(axis_)
157  {
158  delete axis_;
159  axis_ = 0;
160  delete frustum_;
161  delete trace_;
162  delete grid_;
163  delete box_;
164  delete background_renderer_;
166  }
167 
169 
170  if (graph_shader_program_) {
171  glDeleteShader(graph_shader_program_);
173  }
174 
175  if(fboId_>0)
176  {
177  glDeleteFramebuffers(1, &fboId_);
178  fboId_ = 0;
179  glDeleteTextures(1, &depthTexture_);
180  depthTexture_ = 0;
181  }
182 
183  clear();
184 }
185 
186 //Should only be called in OpenGL thread!
188 {
189  LOGI("Scene::clear()");
190  for(std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.begin(); iter!=pointClouds_.end(); ++iter)
191  {
192  delete iter->second;
193  }
194  for(std::map<int, tango_gl::Axis*>::iterator iter=markers_.begin(); iter!=markers_.end(); ++iter)
195  {
196  delete iter->second;
197  }
198  if(trace_)
199  {
201  }
202  if(graph_)
203  {
204  delete graph_;
205  graph_ = 0;
206  }
207  pointClouds_.clear();
208  markers_.clear();
209  if(grid_)
210  {
211  grid_->SetPosition(kHeightOffset);
212  }
213 }
214 
215 //Should only be called in OpenGL thread!
216 void Scene::SetupViewPort(int w, int h) {
217  if (h == 0) {
218  LOGE("Setup graphic height not valid");
219  }
220  UASSERT(gesture_camera_ != 0);
221  gesture_camera_->SetWindowSize(static_cast<float>(w), static_cast<float>(h));
222  glViewport(0, 0, w, h);
223  if(screenWidth_ != w || fboId_ == 0)
224  {
225  if(fboId_>0)
226  {
227  glDeleteFramebuffers(1, &fboId_);
228  fboId_ = 0;
229  glDeleteTextures(1, &depthTexture_);
230  depthTexture_ = 0;
231  }
232 
233  // Create depth texture
234  glGenTextures(1, &depthTexture_);
235  glBindTexture(GL_TEXTURE_2D, depthTexture_);
236  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
237  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
238  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
239  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
240  glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL);
241  glBindTexture(GL_TEXTURE_2D, 0);
242 
243  // regenerate fbo texture
244  // create a framebuffer object, you need to delete them when program exits.
245  glGenFramebuffers(1, &fboId_);
246  glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
247 
248  // Set the texture to be at the depth attachment point of the FBO
249  glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture_, 0);
250 
251  GLuint status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
252  if ( status != GL_FRAMEBUFFER_COMPLETE)
253  {
254  LOGE("Frame buffer cannot be generated! Status: %in", status);
255  }
256  glBindFramebuffer(GL_FRAMEBUFFER,0);
257  }
258  screenWidth_ = w;
259  screenHeight_ = h;
260 }
261 
262 std::vector<glm::vec4> computeFrustumPlanes(const glm::mat4 & mat, bool normalize = true)
263 {
264  // http://www.txutxi.com/?p=444
265  std::vector<glm::vec4> planes(6);
266 
267  // Left Plane
268  // col4 + col1
269  planes[0].x = mat[0][3] + mat[0][0];
270  planes[0].y = mat[1][3] + mat[1][0];
271  planes[0].z = mat[2][3] + mat[2][0];
272  planes[0].w = mat[3][3] + mat[3][0];
273 
274  // Right Plane
275  // col4 - col1
276  planes[1].x = mat[0][3] - mat[0][0];
277  planes[1].y = mat[1][3] - mat[1][0];
278  planes[1].z = mat[2][3] - mat[2][0];
279  planes[1].w = mat[3][3] - mat[3][0];
280 
281  // Bottom Plane
282  // col4 + col2
283  planes[2].x = mat[0][3] + mat[0][1];
284  planes[2].y = mat[1][3] + mat[1][1];
285  planes[2].z = mat[2][3] + mat[2][1];
286  planes[2].w = mat[3][3] + mat[3][1];
287 
288  // Top Plane
289  // col4 - col2
290  planes[3].x = mat[0][3] - mat[0][1];
291  planes[3].y = mat[1][3] - mat[1][1];
292  planes[3].z = mat[2][3] - mat[2][1];
293  planes[3].w = mat[3][3] - mat[3][1];
294 
295  // Near Plane
296  // col4 + col3
297  planes[4].x = mat[0][3] + mat[0][2];
298  planes[4].y = mat[1][3] + mat[1][2];
299  planes[4].z = mat[2][3] + mat[2][2];
300  planes[4].w = mat[3][3] + mat[3][2];
301 
302  // Far Plane
303  // col4 - col3
304  planes[5].x = mat[0][3] - mat[0][2];
305  planes[5].y = mat[1][3] - mat[1][2];
306  planes[5].z = mat[2][3] - mat[2][2];
307  planes[5].w = mat[3][3] - mat[3][2];
308 
309  //if(normalize)
310  {
311  for(unsigned int i=0;i<planes.size(); ++i)
312  {
313  if(normalize)
314  {
315  float d = std::sqrt(planes[i].x * planes[i].x + planes[i].y * planes[i].y + planes[i].z * planes[i].z); // for normalizing the coordinates
316  planes[i].x/=d;
317  planes[i].y/=d;
318  planes[i].z/=d;
319  planes[i].w/=d;
320  }
321  }
322  }
323 
324  return planes;
325 }
326 
335  const std::vector<glm::vec4> &planes,
336  const pcl::PointXYZ &boxMin,
337  const pcl::PointXYZ &boxMax)
338 {
339  // Indexed for the 'index trick' later
340  const pcl::PointXYZ * box[] = {&boxMin, &boxMax};
341 
342  // We only need to do 6 point-plane tests
343  for (unsigned int i = 0; i < planes.size(); ++i)
344  {
345  // This is the current plane
346  const glm::vec4 &p = planes[i];
347 
348  // p-vertex selection (with the index trick)
349  // According to the plane normal we can know the
350  // indices of the positive vertex
351  const int px = p.x > 0.0f?1:0;
352  const int py = p.y > 0.0f?1:0;
353  const int pz = p.z > 0.0f?1:0;
354 
355  // Dot product
356  // project p-vertex on plane normal
357  // (How far is p-vertex from the origin)
358  const float dp =
359  (p.x*box[px]->x) +
360  (p.y*box[py]->y) +
361  (p.z*box[pz]->z) + p.w;
362 
363  // Doesn't intersect if it is behind the plane
364  if (dp < 0) {return false; }
365  }
366  return true;
367 }
368 
369 //Should only be called in OpenGL thread!
370 int Scene::Render(const float * uvsTransformed, glm::mat4 arViewMatrix, glm::mat4 arProjectionMatrix, const rtabmap::Mesh & occlusionMesh) {
371  UASSERT(gesture_camera_ != 0);
372 
373  if(currentPose_ == 0)
374  {
375  currentPose_ = new rtabmap::Transform(0,0,0,0,0,-M_PI/2.0f);
376  }
377  glm::vec3 position(currentPose_->x(), currentPose_->y(), currentPose_->z());
378  Eigen::Quaternionf quat = currentPose_->getQuaternionf();
379  glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
380  glm::mat4 rotateM;
381  if(!currentPose_->isNull())
382  {
383  rotateM = glm::rotate<float>(float(color_camera_to_display_rotation_)*-1.57079632679489661923132169163975144, glm::vec3(0.0f, 0.0f, 1.0f));
384 
386  {
387  // In first person mode, we directly control camera's motion.
388  gesture_camera_->SetPosition(position);
390  }
391  else
392  {
393  // In third person or top down mode, we follow the camera movement.
395  }
396  }
397 
398  glm::mat4 projectionMatrix = gesture_camera_->GetProjectionMatrix();
399  glm::mat4 viewMatrix = gesture_camera_->GetViewMatrix();
400 
401  bool renderBackgroundCamera =
404  !rtabmap::glmToTransform(arProjectionMatrix).isNull() &&
405  uvsTransformed;
406  if(renderBackgroundCamera)
407  {
408  projectionMatrix = arProjectionMatrix;
409  viewMatrix = arViewMatrix;
410  }
411 
412  rtabmap::Transform openglCamera = GetOpenGLCameraPose();//*rtabmap::Transform(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f);
413  // transform in same coordinate as frustum filtering
414  openglCamera *= rtabmap::Transform(
415  0.0f, 0.0f, 1.0f, 0.0f,
416  0.0f, 1.0f, 0.0f, 0.0f,
417  -1.0f, 0.0f, 0.0f, 0.0f);
418 
419  //Culling
420  std::vector<glm::vec4> planes = computeFrustumPlanes(projectionMatrix*viewMatrix, true);
421  std::vector<PointCloudDrawable*> cloudsToDraw(pointClouds_.size());
422  int oi=0;
423  for(std::map<int, PointCloudDrawable*>::const_iterator iter=pointClouds_.begin(); iter!=pointClouds_.end(); ++iter)
424  {
425  if(!mapRendering_ && iter->first > 0)
426  {
427  break;
428  }
429 
430  if(iter->second->isVisible())
431  {
432  if(intersectFrustumAABB(planes,
433  iter->second->aabbMinWorld(),
434  iter->second->aabbMaxWorld()))
435  {
436  cloudsToDraw[oi++] = iter->second;
437  }
438  }
439  }
440  cloudsToDraw.resize(oi);
441 
442  // First rendering to get depth texture
443  glEnable(GL_DEPTH_TEST);
444  glDepthFunc(GL_LESS);
445  glDepthMask(GL_TRUE);
446  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
447  glDisable (GL_BLEND);
448  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
449 
450  if(backfaceCulling_)
451  {
452  glEnable(GL_CULL_FACE);
453  }
454  else
455  {
456  glDisable(GL_CULL_FACE);
457  }
458 
459  UTimer timer;
460 
461  bool onlineBlending = (renderBackgroundCamera && occlusionMesh.cloud.get() && occlusionMesh.cloud->size()) || (blending_ && gesture_camera_->GetCameraType()!=tango_gl::GestureCamera::kTopOrtho && mapRendering_ && meshRendering_ && cloudsToDraw.size()>1);
462  if(onlineBlending && fboId_)
463  {
464  // set the rendering destination to FBO
465  glBindFramebuffer(GL_FRAMEBUFFER, fboId_);
466 
467  glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
468  glClearColor(1, 1, 1, 1);
469  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
470 
471  if(renderBackgroundCamera)
472  {
473  PointCloudDrawable drawable(occlusionMesh);
474  drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 999.0f);
475  }
476  else
477  {
478  // Draw scene
479  for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
480  {
481  // set large distance to cam to use low res polygons for fast processing
482  (*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, false, false, 999.0f);
483  }
484  }
485 
486  // back to normal window-system-provided framebuffer
487  glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind
488  glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
489  }
490 
492  {
493  glClearColor(0, 0, 0, 0);
494  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
495 
496  for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
497  {
498  // set large distance to cam to use low res polygons for fast processing
499  (*iter)->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_*10.0f, false, false, 999.0f, 0, 0, 0, 0, 0, true);
500  }
501 
502  GLubyte zValue[4];
503  glReadPixels(doubleTapPos_.x*screenWidth_, screenHeight_-doubleTapPos_.y*screenHeight_, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, zValue);
504  float fromFixed = 256.0f/255.0f;
505  float zValueF = float(zValue[0]/255.0f)*fromFixed + float(zValue[1]/255.0f)*fromFixed/255.0f + float(zValue[2]/255.0f)*fromFixed/65025.0f + float(zValue[3]/255.0f)*fromFixed/160581375.0f;
506 
507  if(zValueF != 0.0f)
508  {
509  zValueF = zValueF*2.0-1.0;//NDC
510  glm::vec4 point = glm::inverse(projectionMatrix*viewMatrix)*glm::vec4(doubleTapPos_.x*2.0f-1.0f, (1.0f-doubleTapPos_.y)*2.0f-1.0f, zValueF, 1.0f);
511  point /= point.w;
512  gesture_camera_->SetAnchorOffset(glm::vec3(point.x, point.y, point.z) - position);
513  }
514  }
515  doubleTapOn_ = false;
516 
517  glClearColor(r_, g_, b_, 1.0f);
518  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
519 
520  if(renderBackgroundCamera)
521  {
522  background_renderer_->Draw(uvsTransformed);
523 
524  //To debug occlusion image:
525  //PointCloudDrawable drawable(occlusionMesh);
526  //drawable.Render(projectionMatrix, viewMatrix, true, pointSize_, false, false, 999.0f);
527  }
528 
529  if(!currentPose_->isNull())
530  {
532  {
533  frustum_->SetPosition(position);
535  // Set the frustum scale to 4:3, this doesn't necessarily match the physical
536  // camera's aspect ratio, this is just for visualization purposes.
537  frustum_->SetScale(kFrustumScale);
538  frustum_->Render(projectionMatrix, viewMatrix);
539 
541  glm::vec3 positionCamera(cameraFrame.x(), cameraFrame.y(), cameraFrame.z());
542  Eigen::Quaternionf quatCamera = cameraFrame.getQuaternionf();
543  glm::quat rotationCamera(quatCamera.w(), quatCamera.x(), quatCamera.y(), quatCamera.z());
544 
545  axis_->SetPosition(positionCamera);
546  axis_->SetRotation(rotationCamera);
547  axis_->Render(projectionMatrix, viewMatrix);
548  }
549 
550  trace_->UpdateVertexArray(position);
551  if(traceVisible_)
552  {
553  trace_->Render(projectionMatrix, viewMatrix);
554  }
555  }
556 
557  if(gridVisible_ && !renderBackgroundCamera)
558  {
559  grid_->Render(projectionMatrix, viewMatrix);
560  }
561 
562  if(graphVisible_ && graph_)
563  {
564  graph_->Render(projectionMatrix, viewMatrix);
565  }
566 
567 
568  if(onlineBlending)
569  {
570  glEnable (GL_BLEND);
571  glDepthMask(GL_FALSE);
572  }
573 
574  for(std::vector<PointCloudDrawable*>::const_iterator iter=cloudsToDraw.begin(); iter!=cloudsToDraw.end(); ++iter)
575  {
576  PointCloudDrawable * cloud = *iter;
577 
579  {
580  box_->updateVertices(cloud->aabbMinWorld(), cloud->aabbMaxWorld());
581  box_->Render(projectionMatrix, viewMatrix);
582  }
583 
584  Eigen::Vector3f cloudToCamera(
585  cloud->getPose().x() - openglCamera.x(),
586  cloud->getPose().y() - openglCamera.y(),
587  cloud->getPose().z() - openglCamera.z());
588  float distanceToCameraSqr = cloudToCamera[0]*cloudToCamera[0] + cloudToCamera[1]*cloudToCamera[1] + cloudToCamera[2]*cloudToCamera[2];
589 
590  cloud->Render(projectionMatrix, viewMatrix, meshRendering_, pointSize_, meshRenderingTexture_, lighting_, distanceToCameraSqr, onlineBlending?depthTexture_:0, screenWidth_, screenHeight_, gesture_camera_->getNearClipPlane(), gesture_camera_->getFarClipPlane(), false, wireFrame_);
591  }
592 
593  if(onlineBlending)
594  {
595  glDisable (GL_BLEND);
596  glDepthMask(GL_TRUE);
597  }
598 
599  //draw markers on foreground
600  for(std::map<int, tango_gl::Axis*>::const_iterator iter=markers_.begin(); iter!=markers_.end(); ++iter)
601  {
602  iter->second->Render(projectionMatrix, viewMatrix);
603  }
604 
605  return (int)cloudsToDraw.size();
606 }
607 
609  gesture_camera_->SetCameraType(camera_type);
610 }
611 
613 {
614  UASSERT(!pose.isNull());
615  if(currentPose_ ==0)
616  {
617  currentPose_ = new rtabmap::Transform(0,0,0,0,0,-M_PI/2.0f);
618  }
619  *currentPose_ = pose;
620 }
621 
622 void Scene::setFOV(float angle)
623 {
625 }
626 void Scene::setOrthoCropFactor(float value)
627 {
629 }
630 void Scene::setGridRotation(float angleDeg)
631 {
632  float angleRad = angleDeg * DEGREE_2_RADIANS;
633  if(grid_)
634  {
635  glm::quat rot = glm::rotate(glm::quat(1,0,0,0), angleRad, glm::vec3(0, 1, 0));
636  grid_->SetRotation(rot);
637  }
638 }
639 
641 {
642  if(fov)
643  {
644  *fov = gesture_camera_->getFOV();
645  }
647 }
648 
649 void Scene::OnTouchEvent(int touch_count,
650  tango_gl::GestureCamera::TouchEvent event, float x0,
651  float y0, float x1, float y1) {
652  UASSERT(gesture_camera_ != 0);
653  if(touch_count == 3)
654  {
655  //doubletap
656  if(!doubleTapOn_)
657  {
658  doubleTapPos_.x = x0;
659  doubleTapPos_.y = y0;
660  doubleTapOn_ = true;
661  }
662  }
663  else
664  {
665  // rotate/translate/zoom
666  gesture_camera_->OnTouchEvent(touch_count, event, x0, y0, x1, y1);
667  }
668 }
669 
671  const std::map<int, rtabmap::Transform> & poses,
672  const std::multimap<int, rtabmap::Link> & links)
673 {
674  LOGI("updateGraph");
675  if(graph_)
676  {
677  delete graph_;
678  graph_ = 0;
679  }
680 
681  //create
682  if(graphVisible_)
683  {
685  graph_ = new GraphDrawable(graph_shader_program_, poses, links);
686  }
687 }
688 
689 void Scene::setGraphVisible(bool visible)
690 {
691  graphVisible_ = visible;
692 }
693 
694 void Scene::setGridVisible(bool visible)
695 {
696  gridVisible_ = visible;
697 }
698 
699 void Scene::setTraceVisible(bool visible)
700 {
701  traceVisible_ = visible;
702 }
703 
704 void Scene::setFrustumVisible(bool visible)
705 {
706  frustumVisible_ = visible;
707 }
708 
709 //Should only be called in OpenGL thread!
711  int id,
712  const rtabmap::Transform & pose)
713 {
714  LOGI("add marker %d", id);
715  std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
716  if(iter == markers_.end())
717  {
718  //create
719  tango_gl::Axis * drawable = new tango_gl::Axis();
720  drawable->SetScale(glm::vec3(0.05f,0.05f,0.05f));
721  drawable->SetLineWidth(5);
722  markers_.insert(std::make_pair(id, drawable));
723  }
724  setMarkerPose(id, pose);
725 }
726 void Scene::setMarkerPose(int id, const rtabmap::Transform & pose)
727 {
728  UASSERT(!pose.isNull());
729  std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
730  if(iter != markers_.end())
731  {
732  glm::vec3 position(pose.x(), pose.y(), pose.z());
733  Eigen::Quaternionf quat = pose.getQuaternionf();
734  glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
735  iter->second->SetPosition(position);
736  iter->second->SetRotation(rotation);
737  }
738 }
739 bool Scene::hasMarker(int id) const
740 {
741  return markers_.find(id) != markers_.end();
742 }
744 {
745  std::map<int, tango_gl::Axis*>::iterator iter=markers_.find(id);
746  if(iter != markers_.end())
747  {
748  delete iter->second;
749  markers_.erase(iter);
750  }
751 }
752 std::set<int> Scene::getAddedMarkers() const
753 {
754  return uKeysSet(markers_);
755 }
756 
758  int id,
759  const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
760  const pcl::IndicesPtr & indices,
761  const rtabmap::Transform & pose)
762 {
763  LOGI("add cloud %d (%d points %d indices)", id, (int)cloud->size(), indices.get()?(int)indices->size():0);
764  std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
765  if(iter != pointClouds_.end())
766  {
767  delete iter->second;
768  pointClouds_.erase(iter);
769  }
770 
771  //create
772  PointCloudDrawable * drawable = new PointCloudDrawable(cloud, indices);
773  drawable->setPose(pose);
774  pointClouds_.insert(std::make_pair(id, drawable));
775 }
776 
778  int id,
779  const rtabmap::Mesh & mesh,
780  const rtabmap::Transform & pose,
781  bool createWireframe)
782 {
783  LOGI("add mesh %d", id);
784  std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
785  if(iter != pointClouds_.end())
786  {
787  delete iter->second;
788  pointClouds_.erase(iter);
789  }
790 
791  //create
792  PointCloudDrawable * drawable = new PointCloudDrawable(mesh, createWireframe);
793  drawable->setPose(pose);
794  pointClouds_.insert(std::make_pair(id, drawable));
795 
796  if(!mesh.pose.isNull() && mesh.cloud->size() && (!mesh.cloud->isOrganized() || mesh.indices->size()))
797  {
798  UTimer time;
799  float height = 0.0f;
800  Eigen::Affine3f affinePose = mesh.pose.toEigen3f();
801  if(mesh.polygons.size())
802  {
803  for(unsigned int i=0; i<mesh.polygons.size(); ++i)
804  {
805  for(unsigned int j=0; j<mesh.polygons[i].vertices.size(); ++j)
806  {
807  pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(mesh.polygons[i].vertices[j]), affinePose);
808  if(pt.z < height)
809  {
810  height = pt.z;
811  }
812  }
813  }
814  }
815  else
816  {
817  if(mesh.cloud->isOrganized())
818  {
819  for(unsigned int i=0; i<mesh.indices->size(); ++i)
820  {
821  pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(mesh.indices->at(i)), affinePose);
822  if(pt.z < height)
823  {
824  height = pt.z;
825  }
826  }
827  }
828  else
829  {
830  for(unsigned int i=0; i<mesh.cloud->size(); ++i)
831  {
832  pcl::PointXYZRGB pt = pcl::transformPoint(mesh.cloud->at(i), affinePose);
833  if(pt.z < height)
834  {
835  height = pt.z;
836  }
837  }
838  }
839  }
840 
841  if(grid_->GetPosition().y == kHeightOffset.y || grid_->GetPosition().y > height)
842  {
843  grid_->SetPosition(glm::vec3(0,height,0));
844  }
845  LOGD("compute min height %f s", time.ticks());
846  }
847 }
848 
849 
850 void Scene::setCloudPose(int id, const rtabmap::Transform & pose)
851 {
852  UASSERT(!pose.isNull());
853  std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
854  if(iter != pointClouds_.end())
855  {
856  iter->second->setPose(pose);
857  }
858 }
859 
860 void Scene::setCloudVisible(int id, bool visible)
861 {
862  std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
863  if(iter != pointClouds_.end())
864  {
865  iter->second->setVisible(visible);
866  }
867 }
868 
869 bool Scene::hasCloud(int id) const
870 {
871  return pointClouds_.find(id) != pointClouds_.end();
872 }
873 
874 bool Scene::hasMesh(int id) const
875 {
876  return pointClouds_.find(id) != pointClouds_.end() && pointClouds_.at(id)->hasMesh();
877 }
878 
879 bool Scene::hasTexture(int id) const
880 {
881  return pointClouds_.find(id) != pointClouds_.end() && pointClouds_.at(id)->hasTexture();
882 }
883 
884 std::set<int> Scene::getAddedClouds() const
885 {
886  return uKeysSet(pointClouds_);
887 }
888 
889 void Scene::updateCloudPolygons(int id, const std::vector<pcl::Vertices> & polygons)
890 {
891  std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
892  if(iter != pointClouds_.end())
893  {
894  iter->second->updatePolygons(polygons);
895  }
896 }
897 
898 void Scene::updateMesh(int id, const rtabmap::Mesh & mesh)
899 {
900  std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
901  if(iter != pointClouds_.end())
902  {
903  iter->second->updateMesh(mesh);
904  }
905 }
906 
907 void Scene::updateGains(int id, float gainR, float gainG, float gainB)
908 {
909  std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
910  if(iter != pointClouds_.end())
911  {
912  iter->second->setGains(gainR, gainG, gainB);
913  }
914 }
915 
916 void Scene::setGridColor(float r, float g, float b)
917 {
918  if(grid_)
919  {
920  grid_->SetColor(r, g, b);
921  }
922 }
float b_
Definition: scene.h:205
d
glm::vec3 GetPosition() const
Definition: transform.cpp:39
void Render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix)
#define NULL
highp_vec4 vec4
Definition: type_vec.hpp:397
static void releaseShaderPrograms()
const glm::vec3 kHeightOffset
Definition: scene.cpp:39
Definition: UTimer.h:46
void addMesh(int id, const rtabmap::Mesh &mesh, const rtabmap::Transform &pose, bool createWireframe=false)
Definition: scene.cpp:777
float g_
Definition: scene.h:204
void setGridVisible(bool visible)
Definition: scene.cpp:694
highp_vec3 vec3
Definition: type_vec.hpp:392
void SetRotation(const glm::quat &rotation)
Definition: transform.cpp:43
BoundingBoxDrawable * box_
Definition: scene.h:173
bool gridVisible_
Definition: scene.h:179
0 degree rotation (natural orientation)
Definition: util.h:197
pcl::IndicesPtr indices
Definition: util.h:177
rtabmap::Transform glmToTransform(const glm::mat4 &mat)
Definition: util.h:142
void updateCloudPolygons(int id, const std::vector< pcl::Vertices > &polygons)
Definition: scene.cpp:889
void OnTouchEvent(int touch_count, tango_gl::GestureCamera::TouchEvent event, float x0, float y0, float x1, float y1)
Definition: scene.cpp:649
void SetLineWidth(const float pixels)
Definition: line.cpp:24
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
bool wireFrame_
Definition: scene.h:202
void SetupViewPort(int w, int h)
Definition: scene.cpp:216
rtabmap::Transform GetOpenGLCameraPose(float *fov=0) const
Definition: scene.cpp:640
static const rtabmap::Transform optical_T_opengl(1.0f, 0.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f, 0.0f, 0.0f, 0.0f,-1.0f, 0.0f)
std::set< int > getAddedMarkers() const
Definition: scene.cpp:752
void setCloudPose(int id, const rtabmap::Transform &pose)
Definition: scene.cpp:850
f
pcl::PointCloud< pcl::PointXYZRGB >::Ptr cloud
Definition: util.h:175
void SetCameraType(CameraType camera_index)
void setFOV(float angle)
Definition: scene.cpp:622
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
std::map< int, PointCloudDrawable * > pointClouds_
Definition: scene.h:187
bool backfaceCulling_
Definition: scene.h:201
void setPose(const rtabmap::Transform &pose)
void setGridColor(float r, float g, float b)
Definition: scene.cpp:916
const glm::vec3 kFrustumScale
Definition: scene.cpp:48
GLuint fboId_
Definition: scene.h:206
glm::mat4 GetTransformationMatrix() const
Definition: transform.cpp:67
highp_quat quat
Quaternion of default single-precision floating-point numbers.
Definition: fwd.hpp:68
std::set< K > uKeysSet(const std::map< K, V > &m)
Definition: UStl.h:186
bool hasMesh(int id) const
Definition: scene.cpp:874
void SetWindowSize(const float width, const float height)
Definition: camera.cpp:46
float r_
Definition: scene.h:203
~Scene()
Definition: scene.cpp:110
GLsizei screenWidth_
Definition: scene.h:208
bool graphVisible_
Definition: scene.h:178
void clear()
Definition: scene.cpp:187
GLM_FUNC_DECL T angle(detail::tquat< T, P > const &x)
BackgroundRenderer * background_renderer_
Definition: scene.h:157
GLuint CreateProgram(const char *vertex_source, const char *fragment_source)
Definition: util.cpp:75
void Render(const glm::mat4 &projectionMatrix, const glm::mat4 &viewMatrix, bool meshRendering=true, float pointSize=3.0f, bool textureRendering=false, bool lighting=true, float distanceToCamSqr=0.0f, const GLuint &depthTexture=0, int screenWidth=0, int screenHeight=0, float nearClipPlane=0, float farClipPlane=0, bool packDepthToColorChannel=false, bool wireFrame=false) const
#define LOGE(...)
GLsizei screenHeight_
Definition: scene.h:209
bool hasCloud(int id) const
Definition: scene.cpp:869
bool meshRenderingTexture_
Definition: scene.h:197
std::vector< pcl::Vertices > polygons
Definition: util.h:178
bool frustumVisible_
Definition: scene.h:181
tango_gl::Frustum * frustum_
Definition: scene.h:167
void removeMarker(int id)
Definition: scene.cpp:743
unsigned int GLuint
Definition: dummy.cpp:78
const std::string kGraphVertexShader
Definition: scene.cpp:50
void DeleteResources()
Definition: scene.cpp:153
void setOrthoCropFactor(float value)
Definition: scene.cpp:626
bool lighting_
Definition: scene.h:200
float getFarClipPlane() const
Definition: camera.h:40
#define UASSERT(condition)
Wrappers of STL for convenient functions.
void updateGains(int id, float gainR, float gainG, float gainB)
Definition: scene.cpp:907
GLM_FUNC_DECL genType normalize(genType const &x)
std::map< int, tango_gl::Axis * > markers_
Definition: scene.h:183
void InitGLContent()
Definition: scene.cpp:117
rtabmap::Transform getPose() const
#define LOGD(...)
void SetFieldOfView(const float fov)
Definition: camera.cpp:52
#define true
Definition: ConvertUTF.c:57
#define GL_FALSE
Definition: dummy.cpp:79
bool isNull() const
Definition: Transform.cpp:107
Scene()
Definition: scene.cpp:71
GraphDrawable * graph_
Definition: scene.h:177
void SetCameraPose(const rtabmap::Transform &pose)
Definition: scene.cpp:612
bool hasMarker(int id) const
Definition: scene.cpp:739
GLuint depthTexture_
Definition: scene.h:207
bool mapRendering_
Definition: scene.h:195
const std::string kGraphFragmentShader
Definition: scene.cpp:61
void addCloud(int id, const pcl::PointCloud< pcl::PointXYZRGB >::Ptr &cloud, const pcl::IndicesPtr &indices, const rtabmap::Transform &pose)
Definition: scene.cpp:757
bool blending_
Definition: scene.h:194
bool doubleTapOn_
Definition: scene.h:210
void setCloudVisible(int id, bool visible)
Definition: scene.cpp:860
std::vector< glm::vec4 > computeFrustumPlanes(const glm::mat4 &mat, bool normalize=true)
Definition: scene.cpp:262
void updateGraph(const std::map< int, rtabmap::Transform > &poses, const std::multimap< int, rtabmap::Link > &links)
Definition: scene.cpp:670
std::set< int > getAddedClouds() const
Definition: scene.cpp:884
void SetColor(const Color &color)
bool hasTexture(int id) const
Definition: scene.cpp:879
cv::Point2f doubleTapPos_
Definition: scene.h:211
void OnTouchEvent(int touch_count, TouchEvent event, float x0, float y0, float x1, float y1)
tango_gl::Trace * trace_
Definition: scene.h:176
rtabmap::ScreenRotation color_camera_to_display_rotation_
Definition: scene.h:185
void addMarker(int id, const rtabmap::Transform &pose)
Definition: scene.cpp:710
GLM_FUNC_DECL detail::tquat< T, P > rotation(detail::tvec3< T, P > const &orig, detail::tvec3< T, P > const &dest)
#define LOGI(...)
void setFrustumVisible(bool visible)
Definition: scene.cpp:704
#define false
Definition: ConvertUTF.c:56
tango_gl::Grid * grid_
Definition: scene.h:170
void SetAnchorPosition(const glm::vec3 &pos, const glm::quat &rotation)
void SetOrthoCropFactor(float value)
Definition: camera.h:34
Eigen::Quaternionf getQuaternionf() const
Definition: Transform.cpp:370
bool intersectFrustumAABB(const std::vector< glm::vec4 > &planes, const pcl::PointXYZ &boxMin, const pcl::PointXYZ &boxMax)
Definition: scene.cpp:334
const pcl::PointXYZ & aabbMaxWorld() const
tango_gl::Axis * axis_
Definition: scene.h:164
void Render(const glm::mat4 &projection_mat, const glm::mat4 &view_mat) const
Definition: line.cpp:25
void UpdateVertexArray(const glm::vec3 &v)
Definition: trace.cpp:26
int Render(const float *uvsTransformed=0, glm::mat4 arViewMatrix=glm::mat4(0), glm::mat4 arProjectionMatrix=glm::mat4(0), const rtabmap::Mesh &occlusionMesh=rtabmap::Mesh())
Definition: scene.cpp:370
void setTraceVisible(bool visible)
Definition: scene.cpp:699
void SetCameraType(tango_gl::GestureCamera::CameraType camera_type)
Definition: scene.cpp:608
void SetAnchorOffset(const glm::vec3 &pos)
ULogger class and convenient macros.
void Draw(const float *transformed_uvs)
#define DEGREE_2_RADIANS
bool meshRendering_
Definition: scene.h:196
double ticks()
Definition: UTimer.cpp:117
void Render(const glm::mat4 &projection_mat, const glm::mat4 &view_mat) const
Definition: axis.cpp:53
void updateMesh(int id, const rtabmap::Mesh &mesh)
Definition: scene.cpp:898
void ClearVertexArray()
Definition: trace.cpp:37
void setGraphVisible(bool visible)
Definition: scene.cpp:689
const pcl::PointXYZ & aabbMinWorld() const
float getNearClipPlane() const
Definition: camera.h:39
void setMarkerPose(int id, const rtabmap::Transform &pose)
Definition: scene.cpp:726
static void createShaderPrograms()
static const rtabmap::Transform opticalRotationInv
Definition: CameraMobile.h:77
bool boundingBoxRendering_
Definition: scene.h:199
Eigen::Affine3f toEigen3f() const
Definition: Transform.cpp:360
CameraType GetCameraType() const
void setGridRotation(float angleDeg)
Definition: scene.cpp:630
void SetPosition(const glm::vec3 &position)
Definition: transform.cpp:35
void updateVertices(const pcl::PointXYZ &min, const pcl::PointXYZ &max)
glm::mat4 GetProjectionMatrix()
Definition: camera.cpp:38
tango_gl::GestureCamera * gesture_camera_
Definition: scene.h:161
void SetScale(const glm::vec3 &scale)
Definition: transform.cpp:51
const tango_gl::Color kGridColor(0.85f, 0.85f, 0.85f)
float pointSize_
Definition: scene.h:198
bool traceVisible_
Definition: scene.h:180
const tango_gl::Color kTraceColor(0.66f, 0.66f, 0.66f)
rtabmap::Transform * currentPose_
Definition: scene.h:189
GLM_FUNC_DECL detail::tmat4x4< T, P > rotate(detail::tmat4x4< T, P > const &m, T const &angle, detail::tvec3< T, P > const &axis)
glm::mat4 GetViewMatrix()
Definition: camera.cpp:34
rtabmap::Transform pose
Definition: util.h:180
GLM_FUNC_DECL matType< T, P > inverse(matType< T, P > const &m)
GLuint graph_shader_program_
Definition: scene.h:192


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Dec 14 2020 03:35:00