18 #if defined(MRPT_ASSIMP_VERSION_MAJOR) && MRPT_ASSIMP_VERSION_MAJOR < 3 21 #include <aiPostProcess.h> 23 #include <assimp/cimport.h> 24 #include <assimp/DefaultLogger.hpp> 25 #include <assimp/LogStream.hpp> 26 #include <assimp/scene.h> 27 #include <assimp/postprocess.h> 42 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 43 void recursive_render(
44 const aiScene* sc,
const aiNode* nd,
45 const std::vector<unsigned int>& textureIds,
46 const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap);
48 const aiMaterial* mtl,
const std::vector<unsigned int>& textureIds,
49 const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap);
50 void set_float4(
float f[4],
float a,
float b,
float c,
float d);
51 void color4_to_float4(
const aiColor4D*
c,
float f[4]);
52 void get_bounding_box(
const aiScene* sc, aiVector3D*
min, aiVector3D* max);
53 void get_bounding_box_for_node(
54 const aiScene* sc,
const aiNode* nd, aiVector3D*
min, aiVector3D* max,
57 const aiScene* scene, std::vector<unsigned int>& textureIds,
58 std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap,
60 #endif // MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 67 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 70 if (!m_assimp_scene->scene)
return;
72 aiScene* scene = (aiScene*)m_assimp_scene->scene;
81 if (!m_textures_loaded)
83 load_textures(scene, m_textureIds, m_textureIdMap, m_modelPath);
84 m_textures_loaded =
true;
87 recursive_render(scene, scene->mRootNode, m_textureIds, m_textureIdMap);
106 writeToStreamRender(out);
108 const bool empty = m_assimp_scene->scene !=
nullptr;
113 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 135 readFromStreamRender(
in);
147 : m_bbox_min(0, 0, 0), m_bbox_max(0, 0, 0), m_textures_loaded(false)
163 #if MRPT_HAS_OPENGL_GLUT 175 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 182 filepath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality);
187 aiVector3D scene_min, scene_max;
189 get_bounding_box(scene, &scene_min, &scene_max);
205 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 228 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 234 aiReleaseImport((aiScene*)scene);
246 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 249 void get_bounding_box_for_node(
250 const aiScene* scene,
const aiNode* nd, aiVector3D*
min, aiVector3D* max,
254 unsigned int n = 0,
t;
257 aiMultiplyMatrix4(trafo, &nd->mTransformation);
259 for (;
n < nd->mNumMeshes; ++
n)
261 const aiMesh* mesh = scene->mMeshes[nd->mMeshes[
n]];
262 for (
t = 0;
t < mesh->mNumVertices; ++
t)
264 aiVector3D tmp = mesh->mVertices[
t];
265 aiTransformVecByMatrix4(&tmp, trafo);
271 max->x = std::max(max->x, tmp.x);
272 max->y = std::max(max->y, tmp.y);
273 max->z = std::max(max->z, tmp.z);
277 for (
n = 0;
n < nd->mNumChildren; ++
n)
279 get_bounding_box_for_node(scene, nd->mChildren[
n],
min, max, trafo);
285 void get_bounding_box(
const aiScene* scene, aiVector3D*
min, aiVector3D* max)
288 aiIdentityMatrix4(&trafo);
291 max->x = max->y = max->z = -1e10f;
292 get_bounding_box_for_node(scene, scene->mRootNode,
min, max, &trafo);
296 void color4_to_float4(
const aiColor4D*
c,
float f[4])
305 void set_float4(
float f[4],
float a,
float b,
float c,
float d)
315 const aiMaterial* mtl,
const std::vector<unsigned int>& textureIds,
316 const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap)
326 float shininess, strength;
335 mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))
339 it = textureIdMap.find(texPath.data);
340 if (it == textureIdMap.end())
342 std::cerr <<
"[CAssimpModel] Error: using un-loaded texture '" 343 << texPath.data <<
"'\n";
347 unsigned int texId = textureIds[it->second.id_idx];
352 set_float4(
c, 0.8f, 0.8f, 0.8f, 1.0f);
354 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
355 color4_to_float4(&diffuse,
c);
358 set_float4(
c, 0.0f, 0.0f, 0.0f, 1.0f);
360 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
361 color4_to_float4(&specular,
c);
364 set_float4(
c, 0.2f, 0.2f, 0.2f, 1.0f);
366 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
367 color4_to_float4(&ambient,
c);
370 set_float4(
c, 0.0f, 0.0f, 0.0f, 1.0f);
372 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
373 color4_to_float4(&emission,
c);
377 ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
378 if (ret1 == AI_SUCCESS)
381 ret2 = aiGetMaterialFloatArray(
382 mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
383 if (ret2 == AI_SUCCESS)
391 set_float4(
c, 0.0f, 0.0f, 0.0f, 0.0f);
396 if (AI_SUCCESS == aiGetMaterialIntegerArray(
397 mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
404 if ((AI_SUCCESS == aiGetMaterialIntegerArray(
405 mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) &&
413 void Color4f(
const aiColor4D*
color)
419 void recursive_render(
420 const aiScene* sc,
const aiNode* nd,
421 const std::vector<unsigned int>& textureIds,
422 const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap)
425 unsigned int n = 0,
t;
426 aiMatrix4x4 m = nd->mTransformation;
434 for (;
n < nd->mNumMeshes; ++
n)
436 const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[
n]];
439 sc->mMaterials[mesh->mMaterialIndex], textureIds, textureIdMap);
441 if (mesh->mNormals ==
nullptr)
446 if (mesh->mColors[0] !=
nullptr)
451 for (
t = 0;
t < mesh->mNumFaces; ++
t)
453 const struct aiFace*
face = &mesh->mFaces[
t];
456 switch (
face->mNumIndices)
474 for (i = 0; i <
face->mNumIndices;
479 if (mesh->mColors[0] !=
nullptr)
480 Color4f(&mesh->mColors[0][vertexIndex]);
482 if (mesh->HasTextureCoords(
486 mesh->mTextureCoords[0][vertexIndex].x,
488 mesh->mTextureCoords[0][vertexIndex]
503 for (
n = 0;
n < nd->mNumChildren; ++
n)
504 recursive_render(sc, nd->mChildren[
n], textureIds, textureIdMap);
513 if (from.empty())
return;
514 size_t start_pos = 0;
515 while ((start_pos = str.find(from, start_pos)) != std::string::npos)
517 str.replace(start_pos, from.length(), to);
518 start_pos += to.length();
524 const aiScene* scene, std::vector<unsigned int>& textureIds,
525 std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap,
528 if (scene->HasTextures())
530 "Support for meshes with embedded textures is not implemented")
532 textureIdMap.clear();
535 for (
unsigned int m = 0; m < scene->mNumMaterials; m++)
541 aiReturn texFound = scene->mMaterials[m]->GetTexture(
542 aiTextureType_DIFFUSE, texIndex, &path);
543 if (texFound == AI_SUCCESS)
546 ipt.
id_idx = std::string::npos;
555 int numTextures = textureIdMap.size();
558 textureIds.resize(numTextures);
562 numTextures, &textureIds[0]);
567 textureIdMap.begin();
571 for (
int i = 0; i < numTextures; i++)
582 ipt.
img_rgb = mrpt::make_aligned_shared<mrpt::utils::CImage>();
583 ipt.
img_alpha = mrpt::make_aligned_shared<mrpt::utils::CImage>();
593 load_ok = CImage::loadTGA(fileloc, *img_rgb, *img_a);
597 load_ok = img_rgb->loadFromFile(fileloc);
627 const int width = img_rgb->getWidth();
628 const int height = img_rgb->getHeight();
632 const int nBytesPerPixel = img_rgb->isColor() ? 3 : 1;
633 const bool is_RGB_order =
635 img_rgb->getChannelsOrder(),
637 const GLenum img_format = nBytesPerPixel == 3
647 height, 0 , img_format, img_type,
648 img_rgb->get_unsafe(0, 0));
655 "[CAssimpModel] Couldn't load texture image: '%s'",
657 cout << sError << endl;
659 OutputDebugStringA(&sError[0]);
665 #endif // MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP GLAPI void GLAPIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
EIGEN_STRONG_INLINE bool empty() const
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat *m)
GLAPI void GLAPIENTRY glVertex3fv(const GLfloat *v)
GLAPI void GLAPIENTRY glEnable(GLenum cap)
A class for storing images as grayscale or RGB bitmaps.
virtual ~CAssimpModel()
Private, virtual destructor: only can be deleted from smart pointers.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define GL_FRONT_AND_BACK
size_t id_idx
indices in m_textureIds.
#define THROW_EXCEPTION(msg)
GLAPI void GLAPIENTRY glPopMatrix(void)
void evaluateAnimation(double time_anim)
Evaluates the scene at a given animation time.
mrpt::utils::CImage::Ptr img_rgb
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
const Scalar * const_iterator
#define GL_COLOR_MATERIAL
void loadScene(const std::string &file_name)
Loads a scene from a file in any supported file.
GLAPI void GLAPIENTRY glTexCoord2f(GLfloat s, GLfloat t)
mrpt::math::TPoint3D m_bbox_min
Bounding box.
mrpt::poses::CPose3D m_pose
6D pose wrt the parent coordinate reference.
void clear()
Clear the contents of this container.
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's display lists.
GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture)
std::map< std::string, TInfoPerTexture > m_textureIdMap
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
mrpt::utils::CImage::Ptr img_alpha
This base provides a set of functions for maths stuff.
mrpt::math::TPoint3D m_bbox_max
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 '/'->'\' , in Linux/MacOS: replace all '\'->'/'.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
GLAPI void GLAPIENTRY glNormal3fv(const GLfloat *v)
GLAPI void GLAPIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
double x
X,Y,Z coordinates.
std::string extractFileExtension(const std::string &filePath, bool ignore_gz=false)
Extract the extension of a filename.
GLAPI void GLAPIENTRY glBegin(GLenum mode)
GLsizei const GLchar ** string
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
GLAPI void GLAPIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define GL_UNPACK_ROW_LENGTH
#define GL_TEXTURE_MIN_FILTER
void readFromStream(mrpt::utils::CStream &in, int version) override
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
#define GL_UNPACK_ALIGNMENT
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
#define GL_TEXTURE_MAG_FILTER
GLAPI void GLAPIENTRY glPolygonMode(GLenum face, GLenum mode)
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=nullptr, 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...
GLAPI void GLAPIENTRY glGenTextures(GLsizei n, GLuint *textures)
The namespace for 3D scene representation and rendering.
GLAPI void GLAPIENTRY glEnd(void)
#define GL_LIGHT_MODEL_TWO_SIDE
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
void render_dl() const override
Render child objects.
GLAPI void GLAPIENTRY glPushMatrix(void)
GLenum GLsizei GLsizei height
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLubyte GLubyte GLubyte a
GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param)
GLAPI void GLAPIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
This class can load & render 3D models in a number of different formats (requires the library assimp)...
std::vector< unsigned int > m_textureIds
std::string extractFileDirectory(const std::string &filePath)
Extract the whole path (the directory) of a filename from a complete path plus name plus extension...
GLAPI void GLAPIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
GLenum GLuint GLint GLenum face
std::shared_ptr< TImplAssimp > m_assimp_scene