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>
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);
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,
58 const aiScene* scene, std::vector<unsigned int>& textureIds,
59 std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap,
68 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
71 if (!m_assimp_scene->scene)
return;
73 aiScene* scene = (aiScene*)m_assimp_scene->scene;
82 if (!m_textures_loaded)
84 load_textures(scene, m_textureIds, m_textureIdMap, m_modelPath);
85 m_textures_loaded =
true;
88 recursive_render(scene, scene->mRootNode, m_textureIds, m_textureIdMap);
100 writeToStreamRender(out);
102 const bool empty = m_assimp_scene->scene !=
nullptr;
107 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
125 readFromStreamRender(
in);
137 : m_bbox_min(0, 0, 0), m_bbox_max(0, 0, 0), m_textures_loaded(false)
153 #if MRPT_HAS_OPENGL_GLUT
165 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
172 filepath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality);
177 aiVector3D scene_min, scene_max;
179 get_bounding_box(scene, &scene_min, &scene_max);
195 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
218 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
224 aiReleaseImport((aiScene*)scene);
236 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
239 void get_bounding_box_for_node(
240 const aiScene* scene,
const aiNode* nd, aiVector3D*
min, aiVector3D* max,
244 unsigned int n = 0,
t;
247 aiMultiplyMatrix4(trafo, &nd->mTransformation);
249 for (;
n < nd->mNumMeshes; ++
n)
251 const aiMesh* mesh = scene->mMeshes[nd->mMeshes[
n]];
252 for (
t = 0;
t < mesh->mNumVertices; ++
t)
254 aiVector3D tmp = mesh->mVertices[
t];
255 aiTransformVecByMatrix4(&tmp, trafo);
261 max->x = std::max(max->x, tmp.x);
262 max->y = std::max(max->y, tmp.y);
263 max->z = std::max(max->z, tmp.z);
267 for (
n = 0;
n < nd->mNumChildren; ++
n)
269 get_bounding_box_for_node(scene, nd->mChildren[
n],
min, max, trafo);
275 void get_bounding_box(
const aiScene* scene, aiVector3D*
min, aiVector3D* max)
278 aiIdentityMatrix4(&trafo);
281 max->x = max->y = max->z = -1e10f;
282 get_bounding_box_for_node(scene, scene->mRootNode,
min, max, &trafo);
286 void color4_to_float4(
const aiColor4D*
c,
float f[4])
295 void set_float4(
float f[4],
float a,
float b,
float c,
float d)
305 const aiMaterial* mtl,
const std::vector<unsigned int>& textureIds,
306 const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap)
316 float shininess, strength;
325 mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))
329 it = textureIdMap.find(texPath.data);
330 if (it == textureIdMap.end())
332 std::cerr <<
"[CAssimpModel] Error: using un-loaded texture '"
333 << texPath.data <<
"'\n";
337 unsigned int texId = textureIds[it->second.id_idx];
342 set_float4(
c, 0.8f, 0.8f, 0.8f, 1.0f);
344 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
345 color4_to_float4(&diffuse,
c);
348 set_float4(
c, 0.0f, 0.0f, 0.0f, 1.0f);
350 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
351 color4_to_float4(&specular,
c);
354 set_float4(
c, 0.2f, 0.2f, 0.2f, 1.0f);
356 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
357 color4_to_float4(&ambient,
c);
360 set_float4(
c, 0.0f, 0.0f, 0.0f, 1.0f);
362 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
363 color4_to_float4(&emission,
c);
367 ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
368 if (ret1 == AI_SUCCESS)
371 ret2 = aiGetMaterialFloatArray(
372 mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
373 if (ret2 == AI_SUCCESS)
381 set_float4(
c, 0.0f, 0.0f, 0.0f, 0.0f);
386 if (AI_SUCCESS == aiGetMaterialIntegerArray(
387 mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
394 if ((AI_SUCCESS == aiGetMaterialIntegerArray(
395 mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) &&
403 void Color4f(
const aiColor4D*
color)
409 void recursive_render(
410 const aiScene* sc,
const aiNode* nd,
411 const std::vector<unsigned int>& textureIds,
412 const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap)
415 unsigned int n = 0,
t;
416 aiMatrix4x4 m = nd->mTransformation;
424 for (;
n < nd->mNumMeshes; ++
n)
426 const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[
n]];
429 sc->mMaterials[mesh->mMaterialIndex], textureIds, textureIdMap);
431 if (mesh->mNormals ==
nullptr)
436 if (mesh->mColors[0] !=
nullptr)
441 for (
t = 0;
t < mesh->mNumFaces; ++
t)
443 const struct aiFace*
face = &mesh->mFaces[
t];
446 switch (
face->mNumIndices)
464 for (i = 0; i <
face->mNumIndices;
469 if (mesh->mColors[0] !=
nullptr)
470 Color4f(&mesh->mColors[0][vertexIndex]);
472 if (mesh->HasTextureCoords(
476 mesh->mTextureCoords[0][vertexIndex].x,
478 mesh->mTextureCoords[0][vertexIndex]
493 for (
n = 0;
n < nd->mNumChildren; ++
n)
494 recursive_render(sc, nd->mChildren[
n], textureIds, textureIdMap);
503 if (from.empty())
return;
504 size_t start_pos = 0;
505 while ((start_pos = str.find(from, start_pos)) != std::string::npos)
507 str.replace(start_pos, from.length(), to);
508 start_pos += to.length();
514 const aiScene* scene, std::vector<unsigned int>& textureIds,
515 std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap,
518 if (scene->HasTextures())
520 "Support for meshes with embedded textures is not implemented")
522 textureIdMap.
clear();
525 for (
unsigned int m = 0; m < scene->mNumMaterials; m++)
531 aiReturn texFound = scene->mMaterials[m]->GetTexture(
532 aiTextureType_DIFFUSE, texIndex, &path);
533 if (texFound == AI_SUCCESS)
536 ipt.
id_idx = std::string::npos;
545 int numTextures = textureIdMap.size();
548 textureIds.resize(numTextures);
552 numTextures, &textureIds[0]);
557 textureIdMap.begin();
561 for (
int i = 0; i < numTextures; i++)
572 ipt.
img_rgb = mrpt::make_aligned_shared<mrpt::img::CImage>();
573 ipt.
img_alpha = mrpt::make_aligned_shared<mrpt::img::CImage>();
583 load_ok = CImage::loadTGA(fileloc, *img_rgb, *img_a);
622 const int nBytesPerPixel = img_rgb->
isColor() ? 3 : 1;
623 const bool is_RGB_order =
627 const GLenum img_format = nBytesPerPixel == 3
637 height, 0 , img_format, img_type,
645 "[CAssimpModel] Couldn't load texture image: '%s'",
647 cout << sError << endl;
649 OutputDebugStringA(&sError[0]);
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
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 class can load & render 3D models in a number of different formats (requires the library assimp)...
mrpt::math::TPoint3D m_bbox_min
Bounding box.
std::shared_ptr< TImplAssimp > m_assimp_scene
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
virtual ~CAssimpModel()
Private, virtual destructor: only can be deleted from smart pointers.
mrpt::math::TPoint3D m_bbox_max
void clear()
Empty the object.
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const override
Simulation of ray-trace, given a pose.
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
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...
Virtual base class for "archives": classes abstracting I/O streams.
EIGEN_STRONG_INLINE bool empty() const
const Scalar * const_iterator
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
#define THROW_EXCEPTION(msg)
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 format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
std::string lowerCase(const std::string &str)
Returns an lower-case version of a string.
void clear()
Clear the contents of this container.
This base provides a set of functions for maths stuff.
The namespace for 3D scene representation and rendering.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
double x
X,Y,Z coordinates.
size_t id_idx
indices in m_textureIds.
mrpt::img::CImage::Ptr img_alpha
mrpt::img::CImage::Ptr img_rgb