Skip to content

Commit ce4cfc8

Browse files
Only load bones if model has animations
1 parent 1795314 commit ce4cfc8

File tree

3 files changed

+60
-31
lines changed

3 files changed

+60
-31
lines changed

graphics/src/AssimpLoader.cc

+58-31
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class AssimpLoader::Implementation
5151

5252
public: MaterialPtr CreateMaterial(const aiScene* scene, unsigned mat_idx, const std::string& path);
5353

54+
public: void LoadEmbeddedTexture(const aiTexture* texture);
55+
5456
public: SubMesh CreateSubMesh(const aiMesh* assimp_mesh, const ignition::math::Matrix4d& transformation);
5557

5658
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
8890
{
8991
if (!node)
9092
return;
91-
9293
// Visit this node, add the submesh
9394
ignmsg << "Processing node " << node->mName.C_Str() << " with " << node->mNumMeshes << " meshes" << std::endl;
9495
for (unsigned mesh_idx = 0; mesh_idx < node->mNumMeshes; ++mesh_idx)
@@ -110,17 +111,17 @@ void AssimpLoader::Implementation::RecursiveCreate(const aiScene* scene, const a
110111
for (unsigned bone_idx = 0; bone_idx < scene->mMeshes[mesh_idx]->mNumBones; ++bone_idx)
111112
{
112113
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());
114115
// Apply inverse bind transform to the matching node
115116
SkeletonNode *skel_node =
116-
mesh->MeshSkeleton()->NodeByName(bone_name);
117+
mesh->MeshSkeleton()->NodeByName(bone_node_name);
117118
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;
119120
for (unsigned weight_idx = 0; weight_idx < bone->mNumWeights; ++weight_idx)
120121
{
121122
auto vertex_weight = bone->mWeights[weight_idx];
122123
// 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);
124125
//igndbg << "Adding weight at idx " << vertex_weight.mVertexId << " for bone " << bone_name << " of " << vertex_weight.mWeight << std::endl;
125126
}
126127
}
@@ -173,10 +174,8 @@ void AssimpLoader::Implementation::RecursiveSkeletonCreate(const aiNode* node, S
173174
auto node_trans = this->ConvertTransform(node->mTransformation);
174175
igndbg << node_trans << std::endl;
175176
skel_node->SetTransform(node_trans);
176-
//skel_node->SetModelTransform(node_trans.Inverse(), false);
177177
node_trans = transformation * node_trans;
178178

179-
// TODO Set the vertex weights
180179
for (unsigned child_idx = 0; child_idx < node->mNumChildren; ++child_idx)
181180
{
182181
this->RecursiveSkeletonCreate(node->mChildren[child_idx], skel_node, node_trans);
@@ -188,7 +187,7 @@ MaterialPtr AssimpLoader::Implementation::CreateMaterial(const aiScene* scene, u
188187
{
189188
MaterialPtr mat = std::make_shared<Material>();
190189
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;
192191
auto ret = scene->mMaterials[mat_idx]->Get(AI_MATKEY_COLOR_DIFFUSE, color);
193192
if (ret == AI_SUCCESS)
194193
{
@@ -215,28 +214,54 @@ MaterialPtr AssimpLoader::Implementation::CreateMaterial(const aiScene* scene, u
215214
{
216215
mat->SetShininess(shininess);
217216
}
218-
// TODO more than one texture
217+
// TODO more than one texture, Gazebo assumes UV index 0
219218
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
228221
if (ret == AI_SUCCESS)
229222
{
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)
232226
{
233-
227+
// Load embedded texture
228+
ignmsg << "Found embedded texture " << texturePath.C_Str() << std::endl;
229+
this->LoadEmbeddedTexture(embeddedTexture);
234230
}
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()));
235248
}
249+
mat->SetPbrMaterial(pbr);
236250
// TODO other properties
237251
return mat;
238252
}
239253

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+
240265
SubMesh AssimpLoader::Implementation::CreateSubMesh(const aiMesh* assimp_mesh, const ignition::math::Matrix4d& transformation)
241266
{
242267
SubMesh subMesh;
@@ -309,6 +334,7 @@ Mesh *AssimpLoader::Load(const std::string &_filename)
309334
//aiProcess_JoinIdenticalVertices |
310335
aiProcess_RemoveRedundantMaterials |
311336
aiProcess_SortByPType |
337+
aiProcess_PopulateArmatureData |
312338
aiProcess_Triangulate |
313339
0);
314340
if (scene == nullptr)
@@ -335,22 +361,23 @@ Mesh *AssimpLoader::Load(const std::string &_filename)
335361
auto mat = this->dataPtr->CreateMaterial(scene, mat_idx, path);
336362
mesh->AddMaterial(mat);
337363
}
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())
342365
{
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);
346377
}
347-
SkeletonPtr root_skeleton = std::make_shared<Skeleton>(root_skel_node);
348-
mesh->SetSkeleton(root_skeleton);
349-
350378
// Now create the meshes
351379
// Recursive call to keep track of transforms, mesh is passed by reference and edited throughout
352380
this->dataPtr->RecursiveCreate(scene, root_node, root_transformation, mesh);
353-
354381
// Add the animations
355382
for (unsigned anim_idx = 0; anim_idx < scene->mNumAnimations; ++anim_idx)
356383
{

graphics/src/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ ign_build_tests(
2929
ignition-common${IGN_COMMON_VER}-testing
3030
)
3131

32+
message ("ASSIMP INCLUDE IS ${ASSIMP_INCLUDE_DIRS}")
3233
if(USE_EXTERNAL_TINYXML2)
3334

3435
# If we are using an external copy of tinyxml2, add its imported target

graphics/src/MeshManager.cc

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ MeshManager::MeshManager()
105105
this->dataPtr->fileExtensions.push_back("dae");
106106
this->dataPtr->fileExtensions.push_back("obj");
107107
this->dataPtr->fileExtensions.push_back("gltf");
108+
this->dataPtr->fileExtensions.push_back("glb");
108109
this->dataPtr->fileExtensions.push_back("fbx");
109110

110111
}

0 commit comments

Comments
 (0)