@@ -51,6 +51,8 @@ class AssimpLoader::Implementation
51
51
52
52
public: MaterialPtr CreateMaterial (const aiScene* scene, unsigned mat_idx, const std::string& path);
53
53
54
+ public: void LoadEmbeddedTexture (const aiTexture* texture);
55
+
54
56
public: SubMesh CreateSubMesh (const aiMesh* assimp_mesh, const ignition::math::Matrix4d& transformation);
55
57
56
58
public: std::unordered_map<std::string, ignition::math::Matrix4d> PopulateTransformMap (const aiScene* scene);
@@ -88,7 +90,6 @@ void AssimpLoader::Implementation::RecursiveCreate(const aiScene* scene, const a
88
90
{
89
91
if (!node)
90
92
return ;
91
-
92
93
// Visit this node, add the submesh
93
94
ignmsg << " Processing node " << node->mName .C_Str () << " with " << node->mNumMeshes << " meshes" << std::endl;
94
95
for (unsigned mesh_idx = 0 ; mesh_idx < node->mNumMeshes ; ++mesh_idx)
@@ -110,17 +111,17 @@ void AssimpLoader::Implementation::RecursiveCreate(const aiScene* scene, const a
110
111
for (unsigned bone_idx = 0 ; bone_idx < scene->mMeshes [mesh_idx]->mNumBones ; ++bone_idx)
111
112
{
112
113
auto bone = assimp_mesh->mBones [bone_idx];
113
- auto bone_name = std::string (bone->mName .C_Str ());
114
+ auto bone_node_name = std::string (bone-> mNode ->mName .C_Str ());
114
115
// Apply inverse bind transform to the matching node
115
116
SkeletonNode *skel_node =
116
- mesh->MeshSkeleton ()->NodeByName (bone_name );
117
+ mesh->MeshSkeleton ()->NodeByName (bone_node_name );
117
118
skel_node->SetInverseBindTransform (this ->ConvertTransform (bone->mOffsetMatrix ));
118
- igndbg << " Bone " << bone_name << " has " << bone->mNumWeights << " weights" << std::endl;
119
+ igndbg << " Bone " << bone_node_name << " has " << bone->mNumWeights << " weights" << std::endl;
119
120
for (unsigned weight_idx = 0 ; weight_idx < bone->mNumWeights ; ++weight_idx)
120
121
{
121
122
auto vertex_weight = bone->mWeights [weight_idx];
122
123
// TODO SetNumVertAttached for performance
123
- skeleton->AddVertNodeWeight (vertex_weight.mVertexId , bone_name , vertex_weight.mWeight );
124
+ skeleton->AddVertNodeWeight (vertex_weight.mVertexId , bone_node_name , vertex_weight.mWeight );
124
125
// igndbg << "Adding weight at idx " << vertex_weight.mVertexId << " for bone " << bone_name << " of " << vertex_weight.mWeight << std::endl;
125
126
}
126
127
}
@@ -173,10 +174,8 @@ void AssimpLoader::Implementation::RecursiveSkeletonCreate(const aiNode* node, S
173
174
auto node_trans = this ->ConvertTransform (node->mTransformation );
174
175
igndbg << node_trans << std::endl;
175
176
skel_node->SetTransform (node_trans);
176
- // skel_node->SetModelTransform(node_trans.Inverse(), false);
177
177
node_trans = transformation * node_trans;
178
178
179
- // TODO Set the vertex weights
180
179
for (unsigned child_idx = 0 ; child_idx < node->mNumChildren ; ++child_idx)
181
180
{
182
181
this ->RecursiveSkeletonCreate (node->mChildren [child_idx], skel_node, node_trans);
@@ -188,7 +187,7 @@ MaterialPtr AssimpLoader::Implementation::CreateMaterial(const aiScene* scene, u
188
187
{
189
188
MaterialPtr mat = std::make_shared<Material>();
190
189
aiColor4D color;
191
- igndbg << " Processing material with name " << scene->mMaterials [mat_idx]->GetName ().C_Str () << std::endl;
190
+ // igndbg << "Processing material with name " << scene->mMaterials[mat_idx]->GetName().C_Str() << std::endl;
192
191
auto ret = scene->mMaterials [mat_idx]->Get (AI_MATKEY_COLOR_DIFFUSE, color);
193
192
if (ret == AI_SUCCESS)
194
193
{
@@ -215,28 +214,54 @@ MaterialPtr AssimpLoader::Implementation::CreateMaterial(const aiScene* scene, u
215
214
{
216
215
mat->SetShininess (shininess);
217
216
}
218
- // TODO more than one texture
217
+ // TODO more than one texture, Gazebo assumes UV index 0
219
218
aiString texturePath (path.c_str ());
220
- unsigned textureIndex = 0 ;
221
- unsigned uvIndex = 10000 ;
222
- ret = scene->mMaterials [mat_idx]->GetTexture (aiTextureType_DIFFUSE, textureIndex, &texturePath,
223
- NULL , // Type of mapping, TODO check that it is UV
224
- &uvIndex,
225
- NULL , // Blend mode, TODO implement
226
- NULL , // Texture operation, unneeded?
227
- NULL ); // Mapping modes, unneeded?
219
+ ret = scene->mMaterials [mat_idx]->GetTexture (aiTextureType_DIFFUSE, 0 , &texturePath);
220
+ // TODO check other arguments, type of mappings to be UV, uv index, blend mode
228
221
if (ret == AI_SUCCESS)
229
222
{
230
- mat->SetTextureImage (std::string (texturePath.C_Str ()), path.c_str ());
231
- if (uvIndex < 10000 )
223
+ // Check if the texture is embedded or not
224
+ auto embeddedTexture = scene->GetEmbeddedTexture (texturePath.C_Str ());
225
+ if (embeddedTexture)
232
226
{
233
-
227
+ // Load embedded texture
228
+ ignmsg << " Found embedded texture " << texturePath.C_Str () << std::endl;
229
+ this ->LoadEmbeddedTexture (embeddedTexture);
234
230
}
231
+ else
232
+ {
233
+ mat->SetTextureImage (std::string (texturePath.C_Str ()), path.c_str ());
234
+ }
235
+ }
236
+ ret = scene->mMaterials [mat_idx]->GetTexture (aiTextureType_METALNESS, 0 , &texturePath);
237
+ Pbr pbr;
238
+ if (ret == AI_SUCCESS)
239
+ {
240
+ ignmsg << " Found metalness map " << texturePath.C_Str () << std::endl;
241
+ pbr.SetMetalnessMap (std::string (texturePath.C_Str ()));
242
+ }
243
+ ret = scene->mMaterials [mat_idx]->GetTexture (aiTextureType_NORMALS, 0 , &texturePath);
244
+ if (ret == AI_SUCCESS)
245
+ {
246
+ ignmsg << " Found normal map " << texturePath.C_Str () << std::endl;
247
+ pbr.SetNormalMap (std::string (texturePath.C_Str ()));
235
248
}
249
+ mat->SetPbrMaterial (pbr);
236
250
// TODO other properties
237
251
return mat;
238
252
}
239
253
254
+ // ////////////////////////////////////////////////
255
+ void AssimpLoader::Implementation::LoadEmbeddedTexture (const aiTexture* texture)
256
+ {
257
+ if (texture->mHeight == 0 )
258
+ {
259
+ ignwarn << " Found not supported compressed format " << texture->achFormatHint << std::endl;
260
+ return ;
261
+ }
262
+ ignmsg << " Processing texture in format " << texture->achFormatHint << std::endl;
263
+ }
264
+
240
265
SubMesh AssimpLoader::Implementation::CreateSubMesh (const aiMesh* assimp_mesh, const ignition::math::Matrix4d& transformation)
241
266
{
242
267
SubMesh subMesh;
@@ -309,6 +334,7 @@ Mesh *AssimpLoader::Load(const std::string &_filename)
309
334
// aiProcess_JoinIdenticalVertices |
310
335
aiProcess_RemoveRedundantMaterials |
311
336
aiProcess_SortByPType |
337
+ aiProcess_PopulateArmatureData |
312
338
aiProcess_Triangulate |
313
339
0 );
314
340
if (scene == nullptr )
@@ -335,22 +361,23 @@ Mesh *AssimpLoader::Load(const std::string &_filename)
335
361
auto mat = this ->dataPtr ->CreateMaterial (scene, mat_idx, path);
336
362
mesh->AddMaterial (mat);
337
363
}
338
- auto root_skel_node = new SkeletonNode (nullptr , root_name, root_name, SkeletonNode::NODE);
339
- root_skel_node->SetTransform (root_transformation);
340
- root_skel_node->SetModelTransform (root_transformation);
341
- for (unsigned child_idx = 0 ; child_idx < root_node->mNumChildren ; ++child_idx)
364
+ if (scene->HasAnimations ())
342
365
{
343
- // First populate the skeleton with the node transforms
344
- // TODO parse different skeletons and merge them
345
- this ->dataPtr ->RecursiveSkeletonCreate (root_node->mChildren [child_idx], root_skel_node, root_transformation);
366
+ auto root_skel_node = new SkeletonNode (nullptr , root_name, root_name, SkeletonNode::NODE);
367
+ root_skel_node->SetTransform (root_transformation);
368
+ root_skel_node->SetModelTransform (root_transformation);
369
+ for (unsigned child_idx = 0 ; child_idx < root_node->mNumChildren ; ++child_idx)
370
+ {
371
+ // First populate the skeleton with the node transforms
372
+ // TODO parse different skeletons and merge them
373
+ this ->dataPtr ->RecursiveSkeletonCreate (root_node->mChildren [child_idx], root_skel_node, root_transformation);
374
+ }
375
+ SkeletonPtr root_skeleton = std::make_shared<Skeleton>(root_skel_node);
376
+ mesh->SetSkeleton (root_skeleton);
346
377
}
347
- SkeletonPtr root_skeleton = std::make_shared<Skeleton>(root_skel_node);
348
- mesh->SetSkeleton (root_skeleton);
349
-
350
378
// Now create the meshes
351
379
// Recursive call to keep track of transforms, mesh is passed by reference and edited throughout
352
380
this ->dataPtr ->RecursiveCreate (scene, root_node, root_transformation, mesh);
353
-
354
381
// Add the animations
355
382
for (unsigned anim_idx = 0 ; anim_idx < scene->mNumAnimations ; ++anim_idx)
356
383
{
0 commit comments