18 #if defined(MRPT_ASSIMP_VERSION_MAJOR) && MRPT_ASSIMP_VERSION_MAJOR < 3 19 #include <aiPostProcess.h> 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> 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 auto* 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);
152 #if MRPT_HAS_OPENGL_GLUT 164 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 171 filepath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality);
176 aiVector3D scene_min, scene_max;
178 get_bounding_box(scene, &scene_min, &scene_max);
194 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 217 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 223 aiReleaseImport((aiScene*)
scene);
235 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP 238 void get_bounding_box_for_node(
239 const aiScene* scene,
const aiNode* nd, aiVector3D*
min, aiVector3D* max,
243 unsigned int n = 0,
t;
246 aiMultiplyMatrix4(trafo, &nd->mTransformation);
248 for (;
n < nd->mNumMeshes; ++
n)
250 const aiMesh* mesh = scene->mMeshes[nd->mMeshes[
n]];
251 for (
t = 0;
t < mesh->mNumVertices; ++
t)
253 aiVector3D tmp = mesh->mVertices[
t];
254 aiTransformVecByMatrix4(&tmp, trafo);
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);
266 for (
n = 0;
n < nd->mNumChildren; ++
n)
268 get_bounding_box_for_node(scene, nd->mChildren[
n],
min, max, trafo);
274 void get_bounding_box(
const aiScene* scene, aiVector3D*
min, aiVector3D* max)
277 aiIdentityMatrix4(&trafo);
280 max->x = max->y = max->z = -1e10f;
281 get_bounding_box_for_node(scene, scene->mRootNode,
min, max, &trafo);
285 void color4_to_float4(
const aiColor4D*
c,
float f[4])
294 void set_float4(
float f[4],
float a,
float b,
float c,
float d)
304 const aiMaterial* mtl,
const std::vector<unsigned int>& textureIds,
305 const std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap)
315 float shininess, strength;
324 mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))
327 auto it = textureIdMap.find(texPath.data);
328 if (it == textureIdMap.end())
330 std::cerr <<
"[CAssimpModel] Error: using un-loaded texture '" 331 << texPath.data <<
"'\n";
335 unsigned int texId = textureIds[it->second.id_idx];
340 set_float4(
c, 0.8f, 0.8f, 0.8f, 1.0f);
342 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
343 color4_to_float4(&diffuse,
c);
346 set_float4(
c, 0.0f, 0.0f, 0.0f, 1.0f);
348 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
349 color4_to_float4(&specular,
c);
352 set_float4(
c, 0.2f, 0.2f, 0.2f, 1.0f);
354 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
355 color4_to_float4(&ambient,
c);
358 set_float4(
c, 0.0f, 0.0f, 0.0f, 1.0f);
360 aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
361 color4_to_float4(&emission,
c);
365 ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
366 if (ret1 == AI_SUCCESS)
369 ret2 = aiGetMaterialFloatArray(
370 mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
371 if (ret2 == AI_SUCCESS)
379 set_float4(
c, 0.0f, 0.0f, 0.0f, 0.0f);
384 if (AI_SUCCESS == aiGetMaterialIntegerArray(
385 mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
392 if ((AI_SUCCESS == aiGetMaterialIntegerArray(
393 mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) &&
401 void Color4f(
const aiColor4D*
color)
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)
413 unsigned int n = 0,
t;
414 aiMatrix4x4 m = nd->mTransformation;
422 for (;
n < nd->mNumMeshes; ++
n)
424 const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[
n]];
427 sc->mMaterials[mesh->mMaterialIndex], textureIds, textureIdMap);
429 if (mesh->mNormals ==
nullptr)
434 if (mesh->mColors[0] !=
nullptr)
439 for (
t = 0;
t < mesh->mNumFaces; ++
t)
441 const struct aiFace*
face = &mesh->mFaces[
t];
444 switch (
face->mNumIndices)
462 for (i = 0; i <
face->mNumIndices;
467 if (mesh->mColors[0] !=
nullptr)
468 Color4f(&mesh->mColors[0][vertexIndex]);
470 if (mesh->HasTextureCoords(
474 mesh->mTextureCoords[0][vertexIndex].x,
475 1 - mesh->mTextureCoords[0][vertexIndex]
490 for (
n = 0;
n < nd->mNumChildren; ++
n)
491 recursive_render(sc, nd->mChildren[
n], textureIds, textureIdMap);
500 if (from.empty())
return;
501 size_t start_pos = 0;
502 while ((start_pos = str.find(from, start_pos)) != std::string::npos)
504 str.replace(start_pos, from.length(), to);
505 start_pos += to.length();
511 const aiScene* scene, std::vector<unsigned int>& textureIds,
512 std::map<std::string, CAssimpModel::TInfoPerTexture>& textureIdMap,
515 if (scene->HasTextures())
517 "Support for meshes with embedded textures is not implemented");
519 textureIdMap.clear();
522 for (
unsigned int m = 0; m < scene->mNumMaterials; m++)
528 aiReturn texFound = scene->mMaterials[m]->GetTexture(
529 aiTextureType_DIFFUSE, texIndex, &path);
530 if (texFound == AI_SUCCESS)
533 ipt.
id_idx = std::string::npos;
542 int numTextures = textureIdMap.size();
545 textureIds.resize(numTextures);
549 numTextures, &textureIds[0]);
553 auto itr = textureIdMap.begin();
557 for (
int i = 0; i < numTextures; i++)
579 load_ok = CImage::loadTGA(fileloc, *img_rgb, *img_a);
618 const int nBytesPerPixel = img_rgb->
isColor() ? 3 : 1;
621 const GLenum img_format = nBytesPerPixel == 3
631 height, 0 , img_format, img_type,
639 "[CAssimpModel] Couldn't load texture image: '%s'",
641 cout << sError << endl;
643 OutputDebugStringA(&sError[0]);
649 #endif // MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP GLAPI void GLAPIENTRY glDeleteTextures(GLsizei n, const GLuint *textures)
void notifyChange() const
Must be called to notify that the object has changed (so, the display list must be updated) ...
double x
X,Y,Z coordinates.
GLAPI void GLAPIENTRY glMultMatrixf(const GLfloat *m)
GLAPI void GLAPIENTRY glVertex3fv(const GLfloat *v)
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixed< double, 3, 3 > *out_jacobian_df_dpoint=nullptr, mrpt::math::CMatrixFixed< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixed< 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 glEnable(GLenum cap)
#define THROW_EXCEPTION(msg)
static Ptr Create(Args &&... args)
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.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
To be added to 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.
size_t getHeight() const override
Returns the height of the image in pixels.
std::string getChannelsOrder() const
As of mrpt 2.0.0, this returns either "GRAY" or "BGR".
#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
bool loadFromFile(const std::string &fileName, int isColor=-1)
Load image from a file, whose format is determined from the extension (internally uses OpenCV)...
This base provides a set of functions for maths stuff.
mrpt::math::TPoint3D m_bbox_max
size_t getWidth() const override
Returns the width of the image in pixels.
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)
~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.
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
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
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.
GLAPI void GLAPIENTRY glGenTextures(GLsizei n, GLuint *textures)
size_t getRowStride() const
Returns the row stride of the image: this is the number of bytes between two consecutive rows...
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)
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