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,
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);
632 const int nBytesPerPixel = img_rgb->
isColor() ? 3 : 1;
633 const bool is_RGB_order =
637 const GLenum img_format = nBytesPerPixel == 3
647 height, 0 , img_format, img_type,
655 "[CAssimpModel] Couldn't load texture image: '%s'",
657 cout << sError << endl;
659 OutputDebugStringA(&sError[0]);
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
This class can load & render 3D models in a number of different formats (requires the library assimp)...
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const override
Introduces a pure virtual method responsible for writing to a CStream.
mrpt::math::TPoint3D m_bbox_min
Bounding box.
std::shared_ptr< TImplAssimp > m_assimp_scene
virtual ~CAssimpModel()
Private, virtual destructor: only can be deleted from smart pointers.
mrpt::math::TPoint3D m_bbox_max
void clear()
Empty the object.
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...
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Simulation of ray-trace, given a pose.
void loadScene(const std::string &file_name)
Loads a scene from a file in any supported file.
std::vector< unsigned int > m_textureIds
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::map< std::string, TInfoPerTexture > m_textureIdMap
void evaluateAnimation(double time_anim)
Evaluates the scene at a given animation time.
void render_dl() const override
Render child objects.
A renderizable object suitable for rendering with OpenGL's display lists.
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated)
mrpt::poses::CPose3D m_pose
6D pose wrt the parent coordinate reference.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
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...
A class for storing images as grayscale or RGB bitmaps.
unsigned char * get_unsafe(unsigned int col, unsigned int row, unsigned int channel=0) const
Access to pixels without checking boundaries - Use normally the () operator better,...
bool loadFromFile(const std::string &fileName, int isColor=-1)
Load image from a file, whose format is determined from the extension (internally uses OpenCV).
size_t getRowStride() const
Returns the row stride of the image: this is the number of bytes between two consecutive rows.
size_t getHeight() const override
Returns the height of the image in pixels.
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
size_t getWidth() const override
Returns the width of the image in pixels.
const char * getChannelsOrder() const
Returns a string of the form "BGR","RGB" or "GRAY" indicating the channels ordering.
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
EIGEN_STRONG_INLINE bool empty() const
const Scalar * const_iterator
GLAPI void GLAPIENTRY glTexCoord2f(GLfloat s, GLfloat t)
#define GL_TEXTURE_MIN_FILTER
GLAPI void GLAPIENTRY glEnable(GLenum cap)
GLAPI void GLAPIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
#define GL_FRONT_AND_BACK
GLAPI void GLAPIENTRY glMaterialf(GLenum face, GLenum pname, GLfloat param)
GLAPI void GLAPIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
GLAPI void GLAPIENTRY glPolygonMode(GLenum face, GLenum mode)
GLAPI void GLAPIENTRY glPushMatrix(void)
GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat *m)
#define GL_UNPACK_ALIGNMENT
GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture)
GLAPI void GLAPIENTRY glBegin(GLenum mode)
GLAPI void GLAPIENTRY glGenTextures(GLsizei n, GLuint *textures)
GLAPI void GLAPIENTRY glVertex3fv(const GLfloat *v)
#define GL_COLOR_MATERIAL
GLAPI void GLAPIENTRY glPopMatrix(void)
GLAPI void GLAPIENTRY glLightModeli(GLenum pname, GLint param)
GLAPI void GLAPIENTRY glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)
GLAPI void GLAPIENTRY glEnd(void)
GLAPI void GLAPIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param)
#define GL_TEXTURE_MAG_FILTER
GLAPI void GLAPIENTRY glDisable(GLenum cap)
#define GL_LIGHT_MODEL_TWO_SIDE
GLAPI void GLAPIENTRY glNormal3fv(const GLfloat *v)
GLAPI void GLAPIENTRY glPixelStorei(GLenum pname, GLint param)
GLAPI void GLAPIENTRY glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
#define GL_UNPACK_ROW_LENGTH
GLenum GLuint GLint GLenum face
GLubyte GLubyte GLubyte a
GLenum GLsizei GLsizei height
GLsizei const GLchar ** string
std::string extractFileExtension(const std::string &filePath, bool ignore_gz=false)
Extract the extension of a filename.
std::string filePathSeparatorsToNative(const std::string &filePath)
Windows: replace all '/'->'\' , in Linux/MacOS: replace all '\'->'/'.
std::string extractFileDirectory(const std::string &filePath)
Extract the whole path (the directory) of a filename from a complete path plus name plus extension.
std::string lowerCase(const std::string &str)
Returns an lower-case version of a string.
for(ctr=DCTSIZE;ctr > 0;ctr--)
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define THROW_EXCEPTION(msg)
This base provides a set of functions for maths stuff.
The namespace for 3D scene representation and rendering.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
void clear()
Clear the contents of this container.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
double x
X,Y,Z coordinates.
size_t id_idx
indices in m_textureIds.
mrpt::utils::CImage::Ptr img_alpha
mrpt::utils::CImage::Ptr img_rgb