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,
61 #endif // MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 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);
587 load_ok = img_rgb->loadFromFile(fileloc);
617 const int width = img_rgb->getWidth();
618 const int height = img_rgb->getHeight();
622 const int nBytesPerPixel = img_rgb->isColor() ? 3 : 1;
623 const bool is_RGB_order =
625 img_rgb->getChannelsOrder(),
627 const GLenum img_format = nBytesPerPixel == 3
637 height, 0 , img_format, img_type,
638 img_rgb->get_unsafe(0, 0));
645 "[CAssimpModel] Couldn't load texture image: '%s'",
647 cout << sError << endl;
649 OutputDebugStringA(&sError[0]);
655 #endif // MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP GLAPI void GLAPIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
EIGEN_STRONG_INLINE bool empty() const
GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat *m)
GLAPI void GLAPIENTRY glVertex3fv(const GLfloat *v)
GLAPI void GLAPIENTRY glEnable(GLenum cap)
#define THROW_EXCEPTION(msg)
void serializeFrom(mrpt::serialization::CArchive &in, uint8_t serial_version) override
Pure virtual method for reading (deserializing) from an abstract archive.
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.
GLAPI void GLAPIENTRY glPopMatrix(void)
void evaluateAnimation(double time_anim)
Evaluates the scene at a given animation time.
EIGEN_STRONG_INLINE void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
#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.
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.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
GLAPI void GLAPIENTRY glBindTexture(GLenum target, GLuint texture)
std::map< std::string, TInfoPerTexture > m_textureIdMap
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 '\'->'/'.
GLAPI void GLAPIENTRY glNormal3fv(const GLfloat *v)
uint8_t serializeGetVersion() const override
Must return the current versioning number of the object.
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
mrpt::img::CImage::Ptr img_rgb
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
Virtual base class for "archives": classes abstracting I/O streams.
#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)
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
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)
void serializeTo(mrpt::serialization::CArchive &out) const override
Pure virtual method for writing (serializing) to an abstract archive.
#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)
void clear()
Clear the contents of this container.
GLAPI void GLAPIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params)
const Scalar * const_iterator
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
A class for storing images as grayscale or RGB bitmaps.
mrpt::img::CImage::Ptr img_alpha