17 # if defined(MRPT_ASSIMP_VERSION_MAJOR) && MRPT_ASSIMP_VERSION_MAJOR<3
20 # include <aiPostProcess.h>
22 # include <assimp/cimport.h>
23 # include <assimp/DefaultLogger.hpp>
24 # include <assimp/LogStream.hpp>
25 # include <assimp/scene.h>
26 # include <assimp/postprocess.h>
41 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
42 void recursive_render (
const aiScene *sc,
const aiNode* nd,
const std::vector<unsigned int> &textureIds,
const std::map<std::string,CAssimpModel::TInfoPerTexture> &textureIdMap);
43 void apply_material(
const aiMaterial *mtl,
const std::vector<unsigned int> &textureIds,
const std::map<std::string,CAssimpModel::TInfoPerTexture> &textureIdMap);
44 void set_float4(
float f[4],
float a,
float b,
float c,
float d);
45 void color4_to_float4(
const aiColor4D *
c,
float f[4]);
46 void get_bounding_box (
const aiScene *sc,aiVector3D*
min, aiVector3D* max);
47 void get_bounding_box_for_node (
const aiScene *sc,
const aiNode* nd, aiVector3D*
min, aiVector3D* max, aiMatrix4x4* trafo);
48 void load_textures(
const aiScene *scene, std::vector<unsigned int> &textureIds, std::map<std::string,CAssimpModel::TInfoPerTexture> &textureIdMap,
const std::string &modelPath);
56 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
59 if (!m_assimp_scene->scene)
return;
61 aiScene *scene = (aiScene *) m_assimp_scene->scene;
70 if (!m_textures_loaded)
72 load_textures(scene,m_textureIds,m_textureIdMap,m_modelPath);
73 m_textures_loaded =
true;
76 recursive_render(scene, scene->mRootNode,m_textureIds,m_textureIdMap);
95 writeToStreamRender(out);
97 const bool empty = m_assimp_scene->scene!=NULL;
102 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
125 readFromStreamRender(
in);
139 m_textures_loaded(false)
159 #if MRPT_HAS_OPENGL_GLUT
171 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
177 m_assimp_scene->scene = (
void*) aiImportFile(filepath.c_str(), aiProcessPreset_TargetRealtime_MaxQuality );
183 aiVector3D scene_min, scene_max;
185 get_bounding_box(scene,&scene_min,&scene_max);
197 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
223 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
229 aiReleaseImport( (aiScene*) scene);
242 #if MRPT_HAS_OPENGL_GLUT && MRPT_HAS_ASSIMP
245 void get_bounding_box_for_node (
const aiScene* scene,
const aiNode* nd, aiVector3D*
min, aiVector3D* max, aiMatrix4x4* trafo)
248 unsigned int n = 0,
t;
251 aiMultiplyMatrix4(trafo,&nd->mTransformation);
253 for (;
n < nd->mNumMeshes; ++
n) {
254 const aiMesh* mesh = scene->mMeshes[nd->mMeshes[
n]];
255 for (
t = 0;
t < mesh->mNumVertices; ++
t) {
257 aiVector3D tmp = mesh->mVertices[
t];
258 aiTransformVecByMatrix4(&tmp,trafo);
264 max->x = std::max(max->x,tmp.x);
265 max->y = std::max(max->y,tmp.y);
266 max->z = std::max(max->z,tmp.z);
270 for (
n = 0;
n < nd->mNumChildren; ++
n) {
271 get_bounding_box_for_node(scene,nd->mChildren[
n],
min,max,trafo);
277 void get_bounding_box (
const aiScene* scene, aiVector3D*
min, aiVector3D* max)
280 aiIdentityMatrix4(&trafo);
283 max->x = max->y = max->z = -1e10f;
284 get_bounding_box_for_node(scene,scene->mRootNode,
min,max,&trafo);
288 void color4_to_float4(
const aiColor4D *
c,
float f[4])
297 void set_float4(
float f[4],
float a,
float b,
float c,
float d)
306 void apply_material(
const aiMaterial *mtl,
const std::vector<unsigned int> &textureIds,
const std::map<std::string,CAssimpModel::TInfoPerTexture> &textureIdMap)
316 float shininess, strength;
325 if(AI_SUCCESS == mtl->GetTexture(aiTextureType_DIFFUSE, texIndex, &texPath))
329 if (it==textureIdMap.end())
331 std::cerr <<
"[CAssimpModel] Error: using un-loaded texture '"<< texPath.data <<
"'\n";
335 unsigned int texId = textureIds[it->second.id_idx];
340 set_float4(
c, 0.8f, 0.8f, 0.8f, 1.0f);
341 if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
342 color4_to_float4(&diffuse,
c);
345 set_float4(
c, 0.0f, 0.0f, 0.0f, 1.0f);
346 if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
347 color4_to_float4(&specular,
c);
350 set_float4(
c, 0.2f, 0.2f, 0.2f, 1.0f);
351 if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
352 color4_to_float4(&ambient,
c);
355 set_float4(
c, 0.0f, 0.0f, 0.0f, 1.0f);
356 if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
357 color4_to_float4(&emission,
c);
361 ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
362 if(ret1 == AI_SUCCESS) {
364 ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
365 if(ret2 == AI_SUCCESS)
372 set_float4(
c, 0.0f, 0.0f, 0.0f, 0.0f);
377 if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
384 if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
391 void Color4f(
const aiColor4D *
color)
397 void recursive_render (
const aiScene *sc,
const aiNode* nd,
const std::vector<unsigned int> &textureIds,
const std::map<std::string,CAssimpModel::TInfoPerTexture> &textureIdMap)
401 aiMatrix4x4 m = nd->mTransformation;
409 for (;
n < nd->mNumMeshes; ++
n)
411 const struct aiMesh* mesh = sc->mMeshes[nd->mMeshes[
n]];
413 apply_material(sc->mMaterials[mesh->mMaterialIndex],textureIds,textureIdMap);
416 if(mesh->mNormals == NULL)
421 if(mesh->mColors[0] != NULL)
426 for (
t = 0;
t < mesh->mNumFaces; ++
t)
428 const struct aiFace*
face = &mesh->mFaces[
t];
431 switch(
face->mNumIndices)
434 case 2: face_mode =
GL_LINES;
break;
441 for(i = 0; i <
face->mNumIndices; i++)
443 int vertexIndex =
face->mIndices[i];
444 if(mesh->mColors[0] != NULL)
445 Color4f(&mesh->mColors[0][vertexIndex]);
447 if(mesh->HasTextureCoords(0))
449 glTexCoord2f(mesh->mTextureCoords[0][vertexIndex].x, 1 - mesh->mTextureCoords[0][vertexIndex].y);
452 if (mesh->mNormals) {
462 for (
n = 0;
n < nd->mNumChildren; ++
n)
463 recursive_render(sc, nd->mChildren[
n],textureIds,textureIdMap);
472 size_t start_pos = 0;
473 while((start_pos = str.find(from, start_pos)) != std::string::npos) {
474 str.replace(start_pos, from.length(), to);
475 start_pos += to.length();
480 const aiScene *scene,
481 std::vector<unsigned int> &textureIds,
482 std::map<std::string,CAssimpModel::TInfoPerTexture> &textureIdMap,
485 if (scene->HasTextures())
THROW_EXCEPTION(
"Support for meshes with embedded textures is not implemented")
487 textureIdMap.
clear();
490 for (
unsigned int m=0; m<scene->mNumMaterials; m++)
496 aiReturn texFound = scene->mMaterials[m]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
497 if (texFound == AI_SUCCESS)
500 ipt.
id_idx = std::string::npos;
507 int numTextures = textureIdMap.size();
510 textureIds.resize(numTextures);
519 for (
int i=0; i<numTextures; i++)
540 load_ok = CImage::loadTGA(fileloc,*img_rgb,*img_a);
572 const int nBytesPerPixel = img_rgb->
isColor() ? 3 : 1;
586 cout << sError << endl;
588 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 getBoundingBox(mrpt::math::TPoint3D &bb_min, mrpt::math::TPoint3D &bb_max) const MRPT_OVERRIDE
Evaluates the bounding box of this object (including possible children) in the coordinate frame of th...
mrpt::math::TPoint3D m_bbox_min
void writeToStream(mrpt::utils::CStream &out, int *getVersion) const
Introduces a pure virtual method responsible for writing to a CStream.
std::shared_ptr< TImplAssimp > m_assimp_scene
void render_dl() const MRPT_OVERRIDE
Render child objects.
virtual ~CAssimpModel()
Private, virtual destructor: only can be deleted from smart pointers.
mrpt::math::TPoint3D m_bbox_max
Bounding box.
bool traceRay(const mrpt::poses::CPose3D &o, double &dist) const MRPT_OVERRIDE
Simulation of ray-trace, given a pose.
void clear()
Empty the object.
void loadScene(const std::string &file_name)
Loads a scene from a file in any supported file.
std::vector< unsigned int > m_textureIds
std::map< std::string, TInfoPerTexture > m_textureIdMap
void evaluateAnimation(double time_anim)
Evaluates the scene at a given animation time.
void readFromStream(mrpt::utils::CStream &in, int version)
Introduces a pure virtual method responsible for loading from a CStream This can not be used directly...
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. This class automatically holds the cached 3x3 rotation m...
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=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=NULL, 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.
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
size_t getHeight() const MRPT_OVERRIDE
Returns the height of the image in pixels.
static CImagePtr Create()
size_t getWidth() const MRPT_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 BASE_IMPEXP extractFileExtension(const std::string &filePath, bool ignore_gz=false)
Extract the extension of a filename.
std::string BASE_IMPEXP filePathSeparatorsToNative(const std::string &filePath)
Windows: replace all '/'->'\' , in Linux/MacOS: replace all '\'->'/'.
std::string BASE_IMPEXP extractFileDirectory(const std::string &filePath)
Extract the whole path (the directory) of a filename from a complete path plus name plus extension.
std::string BASE_IMPEXP lowerCase(const std::string &str)
Returns an lower-case version of a string.
#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 BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
double z
X,Y,Z coordinates.
A container for automatic deletion of lib3ds's scene when the last reference of the smart_ptr's is de...
mrpt::utils::CImagePtr img_alpha
size_t id_idx
indices in m_textureIds. string::npos for non-initialized ones.
mrpt::utils::CImagePtr img_rgb