MRPT  1.9.9
CAssimpModel.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 // This file contains portions of code from Assimp's example:
11 // "Sample_SimpleOpenGL.c"
12 
13 #include "opengl-precomp.h" // Precompiled header
14 
16 
17 #if MRPT_HAS_ASSIMP
18 #if defined(MRPT_ASSIMP_VERSION_MAJOR) && MRPT_ASSIMP_VERSION_MAJOR < 3
19 #include <aiPostProcess.h>
20 #include <aiScene.h>
21 #include <assimp.h>
22 #else
23 #include <assimp/cimport.h>
24 #include <assimp/postprocess.h>
25 #include <assimp/scene.h>
26 #include <assimp/DefaultLogger.hpp>
27 #include <assimp/LogStream.hpp>
28 #endif
29 #endif
30 
32 #include <mrpt/system/filesystem.h>
33 #include "opengl_internals.h"
34 
35 using namespace mrpt;
36 using namespace mrpt::opengl;
37 using namespace mrpt::math;
38 using namespace std;
39 using mrpt::img::CImage;
40 
42 
43 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
44 void recursive_render(
45  const aiScene* sc, const aiNode* nd,
46  const std::vector<unsigned int>& textureIds,
47  const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap);
48 void apply_material(
49  const aiMaterial* mtl, const std::vector<unsigned int>& textureIds,
50  const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap);
51 void set_float4(float f[4], float a, float b, float c, float d);
52 void color4_to_float4(const aiColor4D* c, float f[4]);
53 void get_bounding_box(const aiScene* sc, aiVector3D* min, aiVector3D* max);
54 void get_bounding_box_for_node(
55  const aiScene* sc, const aiNode* nd, aiVector3D* min, aiVector3D* max,
56  aiMatrix4x4* trafo);
57 void load_textures(
58  const aiScene* scene, std::vector<unsigned int>& textureIds,
59  std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap,
60  const std::string& modelPath);
61 #endif // MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
62 
63 /*---------------------------------------------------------------
64  render
65  ---------------------------------------------------------------*/
67 {
68 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
70 
71  if (!m_assimp_scene->scene) return; // No scene
72 
73  auto* scene = (aiScene*)m_assimp_scene->scene;
74 
75  glEnable(GL_TEXTURE_2D);
76  glDisable(GL_CULL_FACE);
77  // glFrontFace(GL_CW);
78 
79  glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
80  glEnable(GL_NORMALIZE);
81 
82  if (!m_textures_loaded)
83  {
84  load_textures(scene, m_textureIds, m_textureIdMap, m_modelPath);
85  m_textures_loaded = true;
86  }
87 
88  recursive_render(scene, scene->mRootNode, m_textureIds, m_textureIdMap);
89 
90  glDisable(GL_NORMALIZE);
91  glDisable(GL_TEXTURE_2D);
92 
93  MRPT_END
94 #endif
95 }
96 
97 uint8_t CAssimpModel::serializeGetVersion() const { return 0; }
99 {
100  writeToStreamRender(out);
101 
102  const bool empty = m_assimp_scene->scene != nullptr;
103  out << empty;
104 
105  if (!empty)
106  {
107 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
108  // aiScene *scene = (aiScene *) m_assimp_scene->scene;
109  THROW_EXCEPTION("MRPT can't serialize Assimp objects yet!");
110 #else
111  THROW_EXCEPTION("MRPT compiled without OpenGL and/or Assimp");
112 #endif
113  }
114 }
115 
117  mrpt::serialization::CArchive& in, uint8_t version)
118 {
119  THROW_EXCEPTION("MRPT can't serialize Assimp objects yet!");
120 
121  switch (version)
122  {
123  case 0:
124  {
125  readFromStreamRender(in);
126 
127  clear();
128  }
129  break;
130  default:
132  };
134 }
135 
136 CAssimpModel::CAssimpModel() : m_bbox_min(0, 0, 0), m_bbox_max(0, 0, 0)
137 {
138  m_assimp_scene = std::make_shared<TImplAssimp>();
139 }
140 
142 /*---------------------------------------------------------------
143  clear
144  ---------------------------------------------------------------*/
146 {
148  m_assimp_scene = std::make_shared<TImplAssimp>();
149  m_modelPath.clear();
150  m_textures_loaded = false;
151 
152 #if MRPT_HAS_OPENGL_GLUT
153  if (!m_textureIds.empty())
154  {
155  glDeleteTextures(m_textureIds.size(), &m_textureIds[0]);
156  m_textureIds.clear();
157  }
158  m_textureIdMap.clear();
159 #endif
160 }
161 
162 void CAssimpModel::loadScene(const std::string& filepath)
163 {
164 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
165  clear();
167 
168  // we are taking one of the postprocessing presets to avoid
169  // spelling out 20+ single postprocessing flags here.
170  m_assimp_scene->scene = (void*)aiImportFile(
171  filepath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality);
172  m_modelPath = filepath;
173 
174  if (m_assimp_scene->scene)
175  {
176  aiVector3D scene_min, scene_max;
177  auto* scene = (aiScene*)m_assimp_scene->scene;
178  get_bounding_box(scene, &scene_min, &scene_max);
179  m_bbox_min.x = scene_min.x;
180  m_bbox_min.y = scene_min.y;
181  m_bbox_min.z = scene_min.z;
182  m_bbox_max.x = scene_max.x;
183  m_bbox_max.y = scene_max.y;
184  m_bbox_max.z = scene_max.z;
185  }
186 
187 #else
188  THROW_EXCEPTION("MRPT compiled without OpenGL and/or Assimp");
189 #endif
190 }
191 
192 void CAssimpModel::evaluateAnimation(double time_anim)
193 {
194 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
195 // if (m_assimp_scene->file)
196 //{
197 // CRenderizableDisplayList::notifyChange();
198 // lib3ds_file_eval( (Lib3dsFile*) m_assimp_scene->file, time_anim );
199 //}
200 #endif
201 }
202 
205 {
206  bb_min = m_bbox_min;
207  bb_max = m_bbox_max;
208 
209  // Convert to coordinates of my parent:
212 }
213 
216 {
217 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
218  if (scene)
219  {
220  // cleanup - calling 'aiReleaseImport' is important, as the library
221  // keeps internal resources until the scene is freed again. Not
222  // doing so can cause severe resource leaking.
223  aiReleaseImport((aiScene*)scene);
224  scene = nullptr;
225  }
226 #endif
227 }
228 
229 bool CAssimpModel::traceRay(const mrpt::poses::CPose3D& o, double& dist) const
230 {
231  // TODO
232  return false;
233 }
234 
235 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
236 
237 // ----------------------------------------------------------------------------
238 void get_bounding_box_for_node(
239  const aiScene* scene, const aiNode* nd, aiVector3D* min, aiVector3D* max,
240  aiMatrix4x4* trafo)
241 {
242  aiMatrix4x4 prev;
243  unsigned int n = 0, t;
244 
245  prev = *trafo;
246  aiMultiplyMatrix4(trafo, &nd->mTransformation);
247 
248  for (; n < nd->mNumMeshes; ++n)
249  {
250  const aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
251  for (t = 0; t < mesh->mNumVertices; ++t)
252  {
253  aiVector3D tmp = mesh->mVertices[t];
254  aiTransformVecByMatrix4(&tmp, trafo);
255 
256  min->x = std::min(min->x, tmp.x);
257  min->y = std::min(min->y, tmp.y);
258  min->z = std::min(min->z, tmp.z);
259 
260  max->x = std::max(max->x, tmp.x);
261  max->y = std::max(max->y, tmp.y);
262  max->z = std::max(max->z, tmp.z);
263  }
264  }
265 
266  for (n = 0; n < nd->mNumChildren; ++n)
267  {
268  get_bounding_box_for_node(scene, nd->mChildren[n], min, max, trafo);
269  }
270  *trafo = prev;
271 }
272 
273 // ----------------------------------------------------------------------------
274 void get_bounding_box(const aiScene* scene, aiVector3D* min, aiVector3D* max)
275 {
276  aiMatrix4x4 trafo;
277  aiIdentityMatrix4(&trafo);
278 
279  min->x = min->y = min->z = 1e10f;
280  max->x = max->y = max->z = -1e10f;
281  get_bounding_box_for_node(scene, scene->mRootNode, min, max, &trafo);
282 }
283 
284 // ----------------------------------------------------------------------------
285 void color4_to_float4(const aiColor4D* c, float f[4])
286 {
287  f[0] = c->r;
288  f[1] = c->g;
289  f[2] = c->b;
290  f[3] = c->a;
291 }
292 
293 // ----------------------------------------------------------------------------
294 void set_float4(float f[4], float a, float b, float c, float d)
295 {
296  f[0] = a;
297  f[1] = b;
298  f[2] = c;
299  f[3] = d;
300 }
301 
302 // ----------------------------------------------------------------------------
303 void apply_material(
304  const aiMaterial* mtl, const std::vector<unsigned int>& textureIds,
305  const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap)
306 {
307  float c[4];
308 
309  GLenum fill_mode;
310  int ret1, ret2;
311  aiColor4D diffuse;
312  aiColor4D specular;
313  aiColor4D ambient;
314  aiColor4D emission;
315  float shininess, strength;
316  int two_sided;
317  int wireframe;
318  unsigned int max;
319 
320  int texIndex = 0;
321  aiString texPath; // contains filename of texture
322 
323  if (AI_SUCCESS ==
324  mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))
325  {
326  // bind texture
327  auto it = textureIdMap.find(texPath.data);
328  if (it == textureIdMap.end())
329  {
330  std::cerr << "[CAssimpModel] Error: using un-loaded texture '"
331  << texPath.data << "'\n";
332  }
333  else
334  {
335  unsigned int texId = textureIds[it->second.id_idx];
336  glBindTexture(GL_TEXTURE_2D, texId);
337  }
338  }
339 
340  set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
341  if (AI_SUCCESS ==
342  aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
343  color4_to_float4(&diffuse, c);
344  glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);
345 
346  set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
347  if (AI_SUCCESS ==
348  aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
349  color4_to_float4(&specular, c);
350  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
351 
352  set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
353  if (AI_SUCCESS ==
354  aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
355  color4_to_float4(&ambient, c);
356  glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);
357 
358  set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
359  if (AI_SUCCESS ==
360  aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
361  color4_to_float4(&emission, c);
362  glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);
363 
364  max = 1;
365  ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
366  if (ret1 == AI_SUCCESS)
367  {
368  max = 1;
369  ret2 = aiGetMaterialFloatArray(
370  mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
371  if (ret2 == AI_SUCCESS)
372  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
373  else
374  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
375  }
376  else
377  {
378  glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
379  set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
380  glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
381  }
382 
383  max = 1;
384  if (AI_SUCCESS == aiGetMaterialIntegerArray(
385  mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
386  fill_mode = wireframe ? GL_LINE : GL_FILL;
387  else
388  fill_mode = GL_FILL;
389  glPolygonMode(GL_FRONT_AND_BACK, fill_mode);
390 
391  max = 1;
392  if ((AI_SUCCESS == aiGetMaterialIntegerArray(
393  mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) &&
394  two_sided)
395  glDisable(GL_CULL_FACE);
396  else
397  glEnable(GL_CULL_FACE);
398 }
399 
400 // Can't send color down as a pointer to aiColor4D because AI colors are ABGR.
401 void Color4f(const aiColor4D* color)
402 {
403  glColor4f(color->r, color->g, color->b, color->a);
404 }
405 
406 // ----------------------------------------------------------------------------
407 void recursive_render(
408  const aiScene* sc, const aiNode* nd,
409  const std::vector<unsigned int>& textureIds,
410  const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap)
411 {
412  unsigned int i;
413  unsigned int n = 0, t;
414  aiMatrix4x4 m = nd->mTransformation;
415 
416  // update transform
417  m.Transpose();
418  glPushMatrix();
419  glMultMatrixf((float*)&m);
420 
421  // draw all meshes assigned to this node
422  for (; n < nd->mNumMeshes; ++n)
423  {
424  const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[n]];
425 
426  apply_material(
427  sc->mMaterials[mesh->mMaterialIndex], textureIds, textureIdMap);
428 
429  if (mesh->mNormals == nullptr)
430  glDisable(GL_LIGHTING);
431  else
432  glEnable(GL_LIGHTING);
433 
434  if (mesh->mColors[0] != nullptr)
435  glEnable(GL_COLOR_MATERIAL);
436  else
437  glDisable(GL_COLOR_MATERIAL);
438 
439  for (t = 0; t < mesh->mNumFaces; ++t)
440  {
441  const struct aiFace* face = &mesh->mFaces[t];
442  GLenum face_mode;
443 
444  switch (face->mNumIndices)
445  {
446  case 1:
447  face_mode = GL_POINTS;
448  break;
449  case 2:
450  face_mode = GL_LINES;
451  break;
452  case 3:
453  face_mode = GL_TRIANGLES;
454  break;
455  default:
456  face_mode = GL_POLYGON;
457  break;
458  }
459 
460  glBegin(face_mode);
461 
462  for (i = 0; i < face->mNumIndices;
463  i++) // go through all vertices in face
464  {
465  int vertexIndex =
466  face->mIndices[i]; // get group index for current index
467  if (mesh->mColors[0] != nullptr)
468  Color4f(&mesh->mColors[0][vertexIndex]);
469 
470  if (mesh->HasTextureCoords(
471  0)) // HasTextureCoords(texture_coordinates_set)
472  {
473  glTexCoord2f(
474  mesh->mTextureCoords[0][vertexIndex].x,
475  1 - mesh->mTextureCoords[0][vertexIndex]
476  .y); // mTextureCoords[channel][vertex]
477  }
478 
479  if (mesh->mNormals)
480  {
481  glNormal3fv(&mesh->mNormals[vertexIndex].x);
482  }
483  glVertex3fv(&mesh->mVertices[vertexIndex].x);
484  }
485  glEnd();
486  }
487  }
488 
489  // draw all children
490  for (n = 0; n < nd->mNumChildren; ++n)
491  recursive_render(sc, nd->mChildren[n], textureIds, textureIdMap);
492 
493  glPopMatrix();
494 }
495 
496 // http://stackoverflow.com/questions/3418231/replace-part-of-a-string-with-another-string
497 void replaceAll(
498  std::string& str, const std::string& from, const std::string& to)
499 {
500  if (from.empty()) return;
501  size_t start_pos = 0;
502  while ((start_pos = str.find(from, start_pos)) != std::string::npos)
503  {
504  str.replace(start_pos, from.length(), to);
505  start_pos += to.length(); // In case 'to' contains 'from', like
506  // replacing 'x' with 'yx'
507  }
508 }
509 
510 void load_textures(
511  const aiScene* scene, std::vector<unsigned int>& textureIds,
512  std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap,
513  const std::string& modelPath)
514 {
515  if (scene->HasTextures())
517  "Support for meshes with embedded textures is not implemented");
518 
519  textureIdMap.clear();
520 
521  /* getTexture Filenames and no. of Textures */
522  for (unsigned int m = 0; m < scene->mNumMaterials; m++)
523  {
524  int texIndex = 0;
525  for (;;)
526  {
527  aiString path; // filename
528  aiReturn texFound = scene->mMaterials[m]->GetTexture(
529  aiTextureType_DIFFUSE, texIndex, &path);
530  if (texFound == AI_SUCCESS)
531  {
532  CAssimpModel::TInfoPerTexture& ipt = textureIdMap[path.data];
533  ipt.id_idx = std::string::npos; // fill map with textures,
534  // pointers still nullptr yet
535  texIndex++;
536  }
537  else
538  break;
539  }
540  }
541 
542  int numTextures = textureIdMap.size();
543 
544  /* create and fill array with GL texture ids */
545  textureIds.resize(numTextures);
546  if (numTextures)
547  {
548  glGenTextures(
549  numTextures, &textureIds[0]); /* Texture name generation */
550  }
551 
552  /* get iterator */
553  auto itr = textureIdMap.begin();
554 
555  std::string basepath = mrpt::system::filePathSeparatorsToNative(
557  for (int i = 0; i < numTextures; i++)
558  {
559  // save IL image ID
560  std::string filename = itr->first; // get filename
561  CAssimpModel::TInfoPerTexture& ipt = itr->second;
562  ipt.id_idx = i; // save texture id for filename in map
563  ++itr; // next texture
564 
565  const std::string fileloc =
566  mrpt::system::filePathSeparatorsToNative(basepath + filename);
567 
570  mrpt::img::CImage* img_rgb = ipt.img_rgb.get();
571  mrpt::img::CImage* img_a = ipt.img_alpha.get();
572 
573  // Load images:
574  // TGA is handled specially since it's not supported by OpenCV:
575  bool load_ok;
577  mrpt::system::extractFileExtension(fileloc)) == string("tga"))
578  {
579  load_ok = CImage::loadTGA(fileloc, *img_rgb, *img_a);
580  }
581  else
582  {
583  load_ok = img_rgb->loadFromFile(fileloc);
584  }
585 
586  if (load_ok)
587  {
588  // success = ilConvertImage(IL_RGB, IL_UNSIGNED_BYTE); /* Convert
589  // every colour component into unsigned byte. If your image contains
590  // alpha channel you can replace IL_RGB with IL_RGBA */
591  glBindTexture(
592  GL_TEXTURE_2D, textureIds[i]); /* Binding of texture name */
593  // redefine standard texture values
594  glTexParameteri(
595  GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /* We will use
596  linear interpolation for magnification
597  filter */
598  glTexParameteri(
599  GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); /* We will use
600  linear interpolation for minifying filter
601  */
602  // glTexImage2D(
603  // GL_TEXTURE_2D,
604  // 0,
605  // 8 /*ilGetInteger(IL_IMAGE_BPP)*/,
606  // /* ilGetInteger(IL_IMAGE_WIDTH)*/,
607  // /*ilGetInteger(IL_IMAGE_HEIGHT)*/,
608  // 0,
609  // /*ilGetInteger(IL_IMAGE_FORMAT)*/,
610  // GL_UNSIGNED_BYTE,
611  // ilGetData()); /* Texture specification */
612 
613  const int width = img_rgb->getWidth();
614  const int height = img_rgb->getHeight();
615 
616  // Prepare image data types:
617  const GLenum img_type = GL_UNSIGNED_BYTE;
618  const int nBytesPerPixel = img_rgb->isColor() ? 3 : 1;
619  // Reverse RGB <-> BGR order?
620  const bool is_RGB_order = (img_rgb->getChannelsOrder() == "RGB");
621  const GLenum img_format = nBytesPerPixel == 3
622  ? (is_RGB_order ? GL_RGB : GL_BGR)
623  : GL_LUMINANCE;
624 
625  // Send image data to OpenGL:
626  glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
627  glPixelStorei(
628  GL_UNPACK_ROW_LENGTH, img_rgb->getRowStride() / nBytesPerPixel);
629  glTexImage2D(
630  GL_TEXTURE_2D, 0 /*level*/, 3 /* RGB components */, width,
631  height, 0 /*border*/, img_format, img_type,
632  img_rgb->ptrLine<uint8_t>(0));
633  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); // Reset
634  }
635  else
636  {
637  /* Error occured */
638  const std::string sError = mrpt::format(
639  "[CAssimpModel] Couldn't load texture image: '%s'",
640  fileloc.c_str());
641  cout << sError << endl;
642 #ifdef _MSC_VER
643  OutputDebugStringA(&sError[0]);
644 #endif
645  }
646  }
647 }
648 
649 #endif // MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
#define MRPT_START
Definition: exceptions.h:241
double x
X,Y,Z coordinates.
Definition: TPoint3D.h:83
#define THROW_EXCEPTION(msg)
Definition: exceptions.h:67
static Ptr Create(Args &&... args)
Definition: img/CImage.h:149
std::string std::string format(std::string_view fmt, ARGS &&... args)
Definition: format.h:26
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
const T * ptrLine(unsigned int row) const
Returns a pointer to the first pixel of the given line.
Definition: img/CImage.h:596
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to all CSerializable-classes implementation files.
size_t id_idx
indices in m_textureIds.
Definition: CAssimpModel.h:72
void evaluateAnimation(double time_anim)
Evaluates the scene at a given animation time.
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:845
std::string getChannelsOrder() const
As of mrpt 2.0.0, this returns either "GRAY" or "BGR".
Definition: CImage.cpp:824
STL namespace.
void loadScene(const std::string &file_name)
Loads a scene from a file in any supported file.
mrpt::math::TPoint3D m_bbox_min
Bounding box.
Definition: CAssimpModel.h:95
mrpt::poses::CPose3D m_pose
6D pose wrt the parent coordinate reference.
Definition: CRenderizable.h:54
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Simulation of ray-trace, given a pose.
A renderizable object suitable for rendering with OpenGL&#39;s display lists.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
Definition: exceptions.h:97
std::map< std::string, TInfoPerTexture > m_textureIdMap
Definition: CAssimpModel.h:101
bool loadFromFile(const std::string &fileName, int isColor=-1)
Load image from a file, whose format is determined from the extension (internally uses OpenCV)...
Definition: CImage.cpp:305
mrpt::img::CImage CImage
Definition: utils/CImage.h:5
This base provides a set of functions for maths stuff.
mrpt::math::TPoint3D m_bbox_max
Definition: CAssimpModel.h:95
size_t getWidth() const override
Returns the width of the image in pixels.
Definition: CImage.cpp:814
void getBoundingBox(mrpt::math::TPoint3D &bb_min, mrpt::math::TPoint3D &bb_max) const override
Evaluates the bounding box of this object (including possible children) in the coordinate frame of th...
std::string lowerCase(const std::string &str)
Returns an lower-case version of a string.
void clear()
Empty the object.
std::string filePathSeparatorsToNative(const std::string &filePath)
Windows: replace all &#39;/&#39;->&#39;\&#39; , in Linux/MacOS: replace all &#39;\&#39;->&#39;/&#39;.
Definition: filesystem.cpp:612
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
~CAssimpModel() override
Private, virtual destructor: only can be deleted from smart pointers.
std::string extractFileExtension(const std::string &filePath, bool ignore_gz=false)
Extract the extension of a filename.
Definition: filesystem.cpp:98
bool empty() const
Definition: ts_hash_map.h:191
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Virtual base class for "archives": classes abstracting I/O streams.
Definition: CArchive.h:54
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
Definition: CImage.cpp:855
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:85
mrpt::vision::TStereoCalibResults out
#define MRPT_END
Definition: exceptions.h:245
size_t getRowStride() const
Returns the row stride of the image: this is the number of bytes between two consecutive rows...
Definition: CImage.cpp:835
The namespace for 3D scene representation and rendering.
Definition: CGlCanvasBase.h:15
const auto bb_max
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::optional_ref< mrpt::math::CMatrixDouble33 > out_jacobian_df_dpoint=std::nullopt, mrpt::optional_ref< mrpt::math::CMatrixDouble36 > out_jacobian_df_dpose=std::nullopt, mrpt::optional_ref< mrpt::math::CMatrixDouble36 > out_jacobian_df_dse3=std::nullopt, bool use_small_rot_approx=false) const
An alternative, slightly more efficient way of doing with G and L being 3D points and P this 6D pose...
const auto bb_min
void render_dl() const override
Render child objects.
Lightweight 3D point.
Definition: TPoint3D.h:90
void clear()
Clear the contents of this container.
Definition: ts_hash_map.h:183
This class can load & render 3D models in a number of different formats (requires the library assimp)...
Definition: CAssimpModel.h:39
std::vector< unsigned int > m_textureIds
Definition: CAssimpModel.h:99
std::string extractFileDirectory(const std::string &filePath)
Extract the whole path (the directory) of a filename from a complete path plus name plus extension...
Definition: filesystem.cpp:78
std::shared_ptr< TImplAssimp > m_assimp_scene
Definition: CAssimpModel.h:92
A class for storing images as grayscale or RGB bitmaps.
Definition: img/CImage.h:147



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7e629e01a Sat Dec 14 00:05:55 2019 +0100 at sáb dic 14 00:15:10 CET 2019