00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include <tango-gl/conversions.h>
00018 #include <tango-gl/gesture_camera.h>
00019
00020 #include <rtabmap/utilite/ULogger.h>
00021 #include <rtabmap/utilite/UStl.h>
00022 #include <rtabmap/core/util3d_filtering.h>
00023
00024 #include "scene.h"
00025 #include "util.h"
00026
00027
00028
00029
00030
00031 const glm::vec3 kHeightOffset = glm::vec3(0.0f, 1.3f, 0.0f);
00032
00033
00034 const tango_gl::Color kTraceColor(0.66f, 0.66f, 0.66f);
00035
00036
00037 const tango_gl::Color kGridColor(0.85f, 0.85f, 0.85f);
00038
00039
00040 const glm::vec3 kFrustumScale = glm::vec3(0.4f, 0.3f, 0.5f);
00041
00042 const std::string kPointCloudVertexShader =
00043 "precision mediump float;\n"
00044 "precision mediump int;\n"
00045 "attribute vec3 vertex;\n"
00046 "attribute vec3 color;\n"
00047 "uniform mat4 mvp;\n"
00048 "uniform float point_size;\n"
00049 "varying vec3 v_color;\n"
00050 "void main() {\n"
00051 " gl_Position = mvp*vec4(vertex.x, vertex.y, vertex.z, 1.0);\n"
00052 " gl_PointSize = point_size;\n"
00053 " v_color = color;\n"
00054 "}\n";
00055 const std::string kPointCloudFragmentShader =
00056 "precision mediump float;\n"
00057 "precision mediump int;\n"
00058 "varying vec3 v_color;\n"
00059 "void main() {\n"
00060 " gl_FragColor = vec4(v_color.z, v_color.y, v_color.x, 1.0);\n"
00061 "}\n";
00062
00063 const std::string kTextureMeshVertexShader =
00064 "precision mediump float;\n"
00065 "precision mediump int;\n"
00066 "attribute vec3 vertex;\n"
00067 "attribute vec2 a_TexCoordinate;\n"
00068 "uniform mat4 mvp;\n"
00069 "varying vec2 v_TexCoordinate;\n"
00070 "void main() {\n"
00071 " gl_Position = mvp*vec4(vertex.x, vertex.y, vertex.z, 1.0);\n"
00072 " v_TexCoordinate = a_TexCoordinate;\n"
00073 "}\n";
00074 const std::string kTextureMeshFragmentShader =
00075 "precision mediump float;\n"
00076 "precision mediump int;\n"
00077 "uniform sampler2D u_Texture;\n"
00078 "varying vec2 v_TexCoordinate;\n"
00079 "void main() {\n"
00080 " gl_FragColor = texture2D(u_Texture, v_TexCoordinate);\n"
00081 "}\n";
00082
00083 const std::string kGraphVertexShader =
00084 "precision mediump float;\n"
00085 "precision mediump int;\n"
00086 "attribute vec3 vertex;\n"
00087 "uniform vec3 color;\n"
00088 "uniform mat4 mvp;\n"
00089 "varying vec3 v_color;\n"
00090 "void main() {\n"
00091 " gl_Position = mvp*vec4(vertex.x, vertex.y, vertex.z, 1.0);\n"
00092 " v_color = color;\n"
00093 "}\n";
00094 const std::string kGraphFragmentShader =
00095 "precision mediump float;\n"
00096 "precision mediump int;\n"
00097 "varying vec3 v_color;\n"
00098 "void main() {\n"
00099 " gl_FragColor = vec4(v_color.z, v_color.y, v_color.x, 1.0);\n"
00100 "}\n";
00101
00102
00103
00104 Scene::Scene() :
00105 gesture_camera_(0),
00106 axis_(0),
00107 frustum_(0),
00108 grid_(0),
00109 trace_(0),
00110 graph_(0),
00111 graphVisible_(true),
00112 traceVisible_(true),
00113 currentPose_(0),
00114 cloud_shader_program_(0),
00115 texture_mesh_shader_program_(0),
00116 graph_shader_program_(0),
00117 mapRendering_(true),
00118 meshRendering_(true),
00119 pointSize_(3.0f) {}
00120
00121 Scene::~Scene() {DeleteResources();}
00122
00123
00124 void Scene::InitGLContent()
00125 {
00126 if(gesture_camera_ != 0)
00127 {
00128 DeleteResources();
00129 }
00130
00131 UASSERT(gesture_camera_ == 0);
00132
00133 gesture_camera_ = new tango_gl::GestureCamera();
00134 axis_ = new tango_gl::Axis();
00135 frustum_ = new tango_gl::Frustum();
00136 trace_ = new tango_gl::Trace();
00137 grid_ = new tango_gl::Grid();
00138 currentPose_ = new rtabmap::Transform();
00139
00140
00141 axis_->SetScale(glm::vec3(0.5f,0.5f,0.5f));
00142 frustum_->SetColor(kTraceColor);
00143 trace_->ClearVertexArray();
00144 trace_->SetColor(kTraceColor);
00145 grid_->SetColor(kGridColor);
00146 grid_->SetPosition(-kHeightOffset);
00147 gesture_camera_->SetCameraType(
00148 tango_gl::GestureCamera::kFirstPerson);
00149
00150 if(cloud_shader_program_ == 0)
00151 {
00152 cloud_shader_program_ = tango_gl::util::CreateProgram(kPointCloudVertexShader.c_str(), kPointCloudFragmentShader.c_str());
00153 UASSERT(cloud_shader_program_ != 0);
00154 }
00155 if(texture_mesh_shader_program_ == 0)
00156 {
00157 texture_mesh_shader_program_ = tango_gl::util::CreateProgram(kTextureMeshVertexShader.c_str(), kTextureMeshFragmentShader.c_str());
00158 UASSERT(texture_mesh_shader_program_ != 0);
00159 }
00160 if(graph_shader_program_ == 0)
00161 {
00162 graph_shader_program_ = tango_gl::util::CreateProgram(kGraphVertexShader.c_str(), kGraphFragmentShader.c_str());
00163 UASSERT(graph_shader_program_ != 0);
00164 }
00165 }
00166
00167
00168 void Scene::DeleteResources() {
00169
00170 LOGI("Scene::DeleteResources()");
00171 if(gesture_camera_)
00172 {
00173 delete gesture_camera_;
00174 delete axis_;
00175 delete frustum_;
00176 delete trace_;
00177 delete grid_;
00178 delete currentPose_;
00179 gesture_camera_ = 0;
00180 }
00181
00182 if (cloud_shader_program_) {
00183 glDeleteShader(cloud_shader_program_);
00184 cloud_shader_program_ = 0;
00185 }
00186 if (texture_mesh_shader_program_) {
00187 glDeleteShader(texture_mesh_shader_program_);
00188 texture_mesh_shader_program_ = 0;
00189 }
00190 if (graph_shader_program_) {
00191 glDeleteShader(graph_shader_program_);
00192 graph_shader_program_ = 0;
00193 }
00194
00195 clear();
00196 }
00197
00198
00199 void Scene::clear()
00200 {
00201 LOGI("Scene::clear()");
00202 for(std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.begin(); iter!=pointClouds_.end(); ++iter)
00203 {
00204 delete iter->second;
00205 }
00206 if(trace_)
00207 {
00208 trace_->ClearVertexArray();
00209 }
00210 if(graph_)
00211 {
00212 delete graph_;
00213 graph_ = 0;
00214 }
00215 pointClouds_.clear();
00216 }
00217
00218
00219 void Scene::SetupViewPort(int w, int h) {
00220 if (h == 0) {
00221 LOGE("Setup graphic height not valid");
00222 }
00223 UASSERT(gesture_camera_ != 0);
00224 gesture_camera_->SetAspectRatio(static_cast<float>(w) /
00225 static_cast<float>(h));
00226 glViewport(0, 0, w, h);
00227 }
00228
00229
00230 int Scene::Render() {
00231 UASSERT(gesture_camera_ != 0);
00232
00233 glEnable(GL_DEPTH_TEST);
00234 glEnable(GL_CULL_FACE);
00235
00236 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
00237 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
00238
00239 if(!currentPose_->isNull())
00240 {
00241 glm::vec3 position(currentPose_->x(), currentPose_->y(), currentPose_->z());
00242 Eigen::Quaternionf quat = currentPose_->getQuaternionf();
00243 glm::quat rotation(quat.w(), quat.x(), quat.y(), quat.z());
00244
00245 if (gesture_camera_->GetCameraType() == tango_gl::GestureCamera::kFirstPerson)
00246 {
00247
00248 gesture_camera_->SetPosition(position);
00249 gesture_camera_->SetRotation(rotation);
00250 }
00251 else
00252 {
00253
00254 gesture_camera_->SetAnchorPosition(position, rotation);
00255
00256 frustum_->SetPosition(position);
00257 frustum_->SetRotation(rotation);
00258
00259
00260 frustum_->SetScale(kFrustumScale);
00261 frustum_->Render(gesture_camera_->GetProjectionMatrix(),
00262 gesture_camera_->GetViewMatrix());
00263
00264 axis_->SetPosition(position);
00265 axis_->SetRotation(rotation);
00266 axis_->Render(gesture_camera_->GetProjectionMatrix(),
00267 gesture_camera_->GetViewMatrix());
00268 }
00269
00270 trace_->UpdateVertexArray(position);
00271 if(traceVisible_)
00272 {
00273 trace_->Render(gesture_camera_->GetProjectionMatrix(),
00274 gesture_camera_->GetViewMatrix());
00275 }
00276 }
00277
00278
00279 grid_->Render(gesture_camera_->GetProjectionMatrix(),
00280 gesture_camera_->GetViewMatrix());
00281
00282 bool frustumCulling = true;
00283 int cloudDrawn=0;
00284 if(mapRendering_ && frustumCulling)
00285 {
00286
00287 pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
00288 std::vector<int> ids(pointClouds_.size());
00289
00290 cloud->resize(pointClouds_.size());
00291 ids.resize(pointClouds_.size());
00292 int oi=0;
00293 for(std::map<int, PointCloudDrawable*>::const_iterator iter=pointClouds_.begin(); iter!=pointClouds_.end(); ++iter)
00294 {
00295 if(!iter->second->getPose().isNull() && iter->second->isVisible())
00296 {
00297 (*cloud)[oi] = pcl::PointXYZ(iter->second->getPose().x(), iter->second->getPose().y(), iter->second->getPose().z());
00298 ids[oi++] = iter->first;
00299 }
00300 }
00301 cloud->resize(oi);
00302 ids.resize(oi);
00303
00304 if(oi)
00305 {
00306 float fov = 45.0f;
00307 rtabmap::Transform openglCamera = GetOpenGLCameraPose(&fov)*rtabmap::Transform(0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f);
00308
00309 openglCamera *= rtabmap::Transform(
00310 0.0f, 0.0f, 1.0f, 0.0f,
00311 0.0f, 1.0f, 0.0f, 0.0f,
00312 -1.0f, 0.0f, 0.0f, 0.0f);
00313 pcl::IndicesPtr indices = rtabmap::util3d::frustumFiltering(
00314 cloud,
00315 pcl::IndicesPtr(new std::vector<int>),
00316 openglCamera,
00317 fov*2.0f,
00318 fov*2.0f,
00319 0.1f,
00320 100.0f);
00321
00322
00323
00324
00325
00326
00327 for(unsigned int i=0; i<indices->size(); ++i)
00328 {
00329 ++cloudDrawn;
00330 pointClouds_.find(ids[indices->at(i)])->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_);
00331 }
00332 }
00333 }
00334 else
00335 {
00336 for(std::map<int, PointCloudDrawable*>::const_iterator iter=pointClouds_.begin(); iter!=pointClouds_.end(); ++iter)
00337 {
00338 if((mapRendering_ || iter->first < 0) && iter->second->isVisible())
00339 {
00340 ++cloudDrawn;
00341 iter->second->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix(), meshRendering_, pointSize_);
00342 }
00343 }
00344 }
00345
00346 if(graphVisible_ && graph_)
00347 {
00348 graph_->Render(gesture_camera_->GetProjectionMatrix(), gesture_camera_->GetViewMatrix());
00349 }
00350
00351 return cloudDrawn;
00352 }
00353
00354 void Scene::SetCameraType(tango_gl::GestureCamera::CameraType camera_type) {
00355 gesture_camera_->SetCameraType(camera_type);
00356 }
00357
00358 void Scene::SetCameraPose(const rtabmap::Transform & pose)
00359 {
00360 UASSERT(currentPose_ != 0);
00361 UASSERT(!pose.isNull());
00362 *currentPose_ = pose;
00363 }
00364
00365 rtabmap::Transform Scene::GetOpenGLCameraPose(float * fov) const
00366 {
00367 if(fov)
00368 {
00369 *fov = gesture_camera_->getFOV();
00370 }
00371 return glmToTransform(gesture_camera_->GetTransformationMatrix());
00372
00373 }
00374
00375 void Scene::OnTouchEvent(int touch_count,
00376 tango_gl::GestureCamera::TouchEvent event, float x0,
00377 float y0, float x1, float y1) {
00378 UASSERT(gesture_camera_ != 0);
00379 gesture_camera_->OnTouchEvent(touch_count, event, x0, y0, x1, y1);
00380 }
00381
00382 void Scene::updateGraph(
00383 const std::map<int, rtabmap::Transform> & poses,
00384 const std::multimap<int, rtabmap::Link> & links)
00385 {
00386 LOGI("updateGraph");
00387 if(graph_)
00388 {
00389 delete graph_;
00390 graph_ = 0;
00391 }
00392
00393
00394 UASSERT(graph_shader_program_ != 0);
00395 graph_ = new GraphDrawable(graph_shader_program_, poses, links);
00396 }
00397
00398 void Scene::setGraphVisible(bool visible)
00399 {
00400 graphVisible_ = visible;
00401 }
00402
00403 void Scene::setTraceVisible(bool visible)
00404 {
00405 traceVisible_ = visible;
00406 }
00407
00408
00409 void Scene::addCloud(
00410 int id,
00411 const pcl::PointCloud<pcl::PointXYZRGB>::Ptr & cloud,
00412 const std::vector<pcl::Vertices> & polygons,
00413 const rtabmap::Transform & pose,
00414 const cv::Mat & image)
00415 {
00416 LOGI("addOrUpdateCloud cloud %d", id);
00417 std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
00418 if(iter != pointClouds_.end())
00419 {
00420 delete iter->second;
00421 pointClouds_.erase(iter);
00422 }
00423
00424
00425 UASSERT(cloud_shader_program_ != 0 && texture_mesh_shader_program_!=0);
00426 PointCloudDrawable * drawable = new PointCloudDrawable(
00427 cloud_shader_program_,
00428 texture_mesh_shader_program_,
00429 cloud,
00430 polygons,
00431 image);
00432 drawable->setPose(pose);
00433 pointClouds_.insert(std::make_pair(id, drawable));
00434 }
00435
00436
00437 void Scene::setCloudPose(int id, const rtabmap::Transform & pose)
00438 {
00439 UASSERT(!pose.isNull());
00440 std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
00441 if(iter != pointClouds_.end())
00442 {
00443 iter->second->setPose(pose);
00444 }
00445 }
00446
00447 void Scene::setCloudVisible(int id, bool visible)
00448 {
00449 std::map<int, PointCloudDrawable*>::iterator iter=pointClouds_.find(id);
00450 if(iter != pointClouds_.end())
00451 {
00452 iter->second->setVisible(visible);
00453 }
00454 }
00455
00456 bool Scene::hasCloud(int id) const
00457 {
00458 return pointClouds_.find(id) != pointClouds_.end();
00459 }
00460
00461 std::set<int> Scene::getAddedClouds() const
00462 {
00463 return uKeysSet(pointClouds_);
00464 }