Skip to content

Commit 4eec15d

Browse files
[backport Humble] load glb meshes (#1154) (#1157)
Signed-off-by: Alejandro Hernández Cordero <[email protected]> (cherry picked from commit 0722bd0) Co-authored-by: Alejandro Hernández Cordero <[email protected]>
1 parent 49196e6 commit 4eec15d

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

rviz_rendering/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,12 @@ target_link_libraries(rviz_rendering
106106
resource_retriever::resource_retriever
107107
)
108108

109+
if("${assimp_VERSION}" VERSION_GREATER 4.1.0)
110+
target_compile_definitions(rviz_rendering PRIVATE ASSIMP_VERSION_5)
111+
else()
112+
message("Warning, assimp below 4.10 detected, disable embedded texture")
113+
endif()
114+
109115
target_include_directories(rviz_rendering
110116
PUBLIC
111117
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>

rviz_rendering/src/rviz_rendering/mesh_loader_helpers/assimp_loader.cpp

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class ResourceIOStream : public Assimp::IOStream
8282
memcpy(buffer, pos_, to_read);
8383
pos_ += to_read;
8484

85-
return to_read;
85+
return to_read / size;
8686
}
8787

8888
size_t Write(const void * buffer, size_t size, size_t count) override
@@ -262,6 +262,7 @@ std::vector<Ogre::MaterialPtr> AssimpLoader::loadMaterials(
262262
Ogre::ColourValue(0, 0, 0, 1.0));
263263

264264

265+
SetScene(scene);
265266
setLightColorsFromAssimp(resource_path, mat, ai_material, material_internals);
266267

267268
setBlending(mat, ai_material, material_internals);
@@ -274,6 +275,11 @@ std::vector<Ogre::MaterialPtr> AssimpLoader::loadMaterials(
274275
return material_table_out;
275276
}
276277

278+
void AssimpLoader::SetScene(const aiScene * ai_scene)
279+
{
280+
this->ai_scene_ = ai_scene;
281+
}
282+
277283
void AssimpLoader::setLightColorsFromAssimp(
278284
const std::string & resource_path,
279285
Ogre::MaterialPtr & mat,
@@ -290,11 +296,24 @@ void AssimpLoader::setLightColorsFromAssimp(
290296
uint32_t uv_index;
291297
ai_material->GetTexture(aiTextureType_DIFFUSE, 0, &texture_name, &mapping, &uv_index);
292298

299+
std::string texture_path;
300+
#ifdef ASSIMP_VERSION_5
301+
const aiTexture * texture = this->ai_scene_->GetEmbeddedTexture(texture_name.C_Str());
302+
if (texture == nullptr) {
303+
#endif
304+
// It's not an embedded texture. We have to go find it.
293305
// Assume textures are in paths relative to the mesh
294306
QFileInfo resource_path_finfo(QString::fromStdString(resource_path));
295307
QDir resource_path_qdir = resource_path_finfo.dir();
296-
std::string texture_path = resource_path_qdir.path().toStdString() + "/" + texture_name.data;
308+
texture_path = resource_path_qdir.path().toStdString() + "/" + texture_name.data;
297309
loadTexture(texture_path);
310+
#ifdef ASSIMP_VERSION_5
311+
} else {
312+
// it's an embedded texture, like in GLB / glTF
313+
texture_path = resource_path + texture_name.data;
314+
loadEmbeddedTexture(texture, texture_path);
315+
}
316+
#endif
298317
Ogre::TextureUnitState * tu = material_internals.pass_->createTextureUnitState();
299318
tu->setTextureName(texture_path);
300319
} else if (propKey == "$clr.diffuse") {
@@ -340,6 +359,35 @@ void AssimpLoader::setLightColorsFromAssimp(
340359
}
341360
}
342361

362+
void AssimpLoader::loadEmbeddedTexture(
363+
const aiTexture * texture, const std::string & resource_path)
364+
{
365+
if (texture == nullptr) {
366+
RVIZ_RENDERING_LOG_ERROR_STREAM("null texture!");
367+
return;
368+
}
369+
370+
// use the format hint to try to load the image
371+
std::string format_hint(
372+
texture->achFormatHint,
373+
strnlen(texture->achFormatHint, sizeof(texture->achFormatHint)));
374+
375+
Ogre::DataStreamPtr stream(
376+
new Ogre::MemoryDataStream(
377+
(unsigned char *)texture->pcData, texture->mWidth));
378+
379+
try {
380+
Ogre::Image image;
381+
image.load(stream, format_hint.c_str());
382+
Ogre::TextureManager::getSingleton().loadImage(
383+
resource_path, ROS_PACKAGE_NAME, image);
384+
} catch (Ogre::Exception & e) {
385+
RVIZ_RENDERING_LOG_ERROR_STREAM(
386+
"Could not load texture [" << resource_path.c_str() <<
387+
"] with format hint [" << format_hint << "]: " << e.what());
388+
}
389+
}
390+
343391
void AssimpLoader::loadTexture(const std::string & resource_path)
344392
{
345393
if (!Ogre::TextureManager::getSingleton().resourceExists(resource_path, ROS_PACKAGE_NAME)) {

rviz_rendering/src/rviz_rendering/mesh_loader_helpers/assimp_loader.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,14 @@ class AssimpLoader
103103

104104
std::vector<Ogre::MaterialPtr> loadMaterials(
105105
const std::string & resource_path, const aiScene * scene);
106+
107+
void SetScene(const aiScene * ai_scene);
108+
const aiScene * ai_scene_;
109+
110+
void loadEmbeddedTexture(
111+
const aiTexture * ai_texture,
112+
const std::string & resource_path);
113+
106114
void setLightColorsFromAssimp(
107115
const std::string & resource_path,
108116
Ogre::MaterialPtr & mat,

0 commit comments

Comments
 (0)