Skip to content

Commit

Permalink
Associate library materials effect with meshes (#151)
Browse files Browse the repository at this point in the history
* Associate library materials effect with meshes

Signed-off-by: ahcorde <[email protected]>

* make linters happy

Signed-off-by: ahcorde <[email protected]>

* Added test

Signed-off-by: ahcorde <[email protected]>

* Added feedback

Signed-off-by: ahcorde <[email protected]>

Co-authored-by: Michael Carroll <[email protected]>
Co-authored-by: Louise Poubel <[email protected]>
  • Loading branch information
3 people authored Feb 5, 2021
1 parent c98d0d2 commit 89b1157
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 0 deletions.
40 changes: 40 additions & 0 deletions graphics/src/ColladaLoader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ namespace ignition
/// \brief material dictionary indexed by name
public: std::map<std::string, std::string> materialMap;

/// \brief material dictionary indexed by mesh name
public: std::map<std::string, std::string> materialEffectMap;

/// \brief root xml element of COLLADA data
public: tinyxml2::XMLElement *colladaXml;

Expand Down Expand Up @@ -528,6 +531,7 @@ void ColladaLoaderPrivate::LoadNode(tinyxml2::XMLElement *_elem, Mesh *_mesh,
tinyxml2::XMLElement *geomXml = this->ElementId("geometry", geomURL);

this->materialMap.clear();
this->materialEffectMap.clear();
tinyxml2::XMLElement *bindMatXml, *techniqueXml, *matXml;
bindMatXml = instGeomXml->FirstChildElement("bind_material");
while (bindMatXml)
Expand All @@ -540,6 +544,7 @@ void ColladaLoaderPrivate::LoadNode(tinyxml2::XMLElement *_elem, Mesh *_mesh,
std::string symbol = matXml->Attribute("symbol");
std::string target = matXml->Attribute("target");
this->materialMap[symbol] = target;
this->materialEffectMap[geomURL] = target;
matXml = matXml->NextSiblingElement("instance_material");
}
}
Expand All @@ -549,6 +554,41 @@ void ColladaLoaderPrivate::LoadNode(tinyxml2::XMLElement *_elem, Mesh *_mesh,
if (_mesh->HasSkeleton())
_mesh->MeshSkeleton()->SetNumVertAttached(0);
this->LoadGeometry(geomXml, transform, _mesh);

// Associate materials defined in library_materials with the right mesh
if (materialEffectMap.size() > 0)
{
std::string matStr;
int matIndex = -1;
std::map<std::string, std::string>::iterator iter;

iter = this->materialEffectMap.find(geomURL);
if (iter != this->materialEffectMap.end())
matStr = iter->second;
MaterialPtr mat = this->LoadMaterial(matStr);
matIndex = _mesh->IndexOfMaterial(mat.get());
if (matIndex < 0)
{
matIndex = _mesh->AddMaterial(mat);
}
if (matIndex < 0)
{
ignwarn << "Unable to add material[" << matStr << "]\n";
}
else
{
auto subMesh = _mesh->SubMeshByName(this->currentNodeName);
if (subMesh.lock() == nullptr)
{
ignwarn << "Unable to get submesh[" << geomURL << "]\n";
}
else
{
subMesh.lock().get()->SetMaterialIndex(matIndex);
}
}
}

instGeomXml = instGeomXml->NextSiblingElement("instance_geometry");
}

Expand Down
27 changes: 27 additions & 0 deletions graphics/src/ColladaLoader_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,33 @@ TEST_F(ColladaLoader, LoadBox)
EXPECT_STREQ("Cube", mesh->SubMeshByIndex(0).lock()->Name().c_str());
}

/////////////////////////////////////////////////
TEST_F(ColladaLoader, LoadRectangle)
{
common::ColladaLoader loader;
common::Mesh *mesh = loader.Load(common::joinPaths(
std::string(PROJECT_SOURCE_PATH), "test", "data", "rectangle.dae"));

EXPECT_STREQ("unknown", mesh->Name().c_str());
EXPECT_EQ(ignition::math::Vector3d(0.35, 0.4, 1), mesh->Max());
EXPECT_EQ(ignition::math::Vector3d(-0.35, -0.4, -1), mesh->Min());
EXPECT_EQ(35u, mesh->VertexCount());
EXPECT_EQ(35u, mesh->NormalCount());
EXPECT_EQ(36u, mesh->IndexCount());
EXPECT_EQ(0u, mesh->TexCoordCount());
EXPECT_EQ(1u, mesh->SubMeshCount());
EXPECT_EQ(1u, mesh->MaterialCount());

common::MaterialPtr material = mesh->MaterialByIndex(0);
EXPECT_NE(nullptr, material);
EXPECT_EQ(math::Color(0.008957128f, 0.00619848f, 0.64f, 1.0f),
material->Diffuse());
EXPECT_EQ(math::Color(0.5, 0.5, 0.5, 1), material->Specular());
EXPECT_EQ(math::Color(0, 0, 0, 1), material->Ambient());
EXPECT_EQ(math::Color(0, 0, 0, 1), material->Emissive());
EXPECT_DOUBLE_EQ(50.0, material->Shininess());
}

/////////////////////////////////////////////////
TEST_F(ColladaLoader, ShareVertices)
{
Expand Down
92 changes: 92 additions & 0 deletions test/data/rectangle.dae
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
<asset>
<unit name="meter" meter="1"/>
<up_axis>Z_UP</up_axis>
</asset>
<library_images/>
<library_effects>
<effect id="effect-cube">
<profile_COMMON>
<technique sid="common">
<phong>
<emission>
<color sid="emission">0 0 0 1</color>
</emission>
<ambient>
<color sid="ambient">0 0 0 1</color>
</ambient>
<diffuse>
<color sid="diffuse">0.008957128 0.00619848 0.64 1</color>
</diffuse>
<specular>
<color sid="specular">0.5 0.5 0.5 1</color>
</specular>
<shininess>
<float sid="shininess">50</float>
</shininess>
<index_of_refraction>
<float sid="index_of_refraction">1</float>
</index_of_refraction>
</phong>
</technique>
</profile_COMMON>
</effect>
</library_effects>
<library_materials>
<material id="material-cube">
<instance_effect url="#effect-cube"/>
</material>
</library_materials>
<library_geometries>
<geometry id="mesh-cube">
<mesh>
<source id="mesh-cube-positions">
<float_array id="mesh-cube-positions-array" count="24">-1 -1 -1 -1 -1 1 -1 1 -1 -1 1 1 1 -1 -1 1 -1 1 1 1 -1 1 1 1</float_array>
<technique_common>
<accessor source="#mesh-cube-positions-array" count="8" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<source id="mesh-cube-normals">
<float_array id="mesh-cube-normals-array" count="18">-1 0 0 0 1 0 1 0 0 0 -1 0 0 0 -1 0 0 1</float_array>
<technique_common>
<accessor source="#mesh-cube-normals-array" count="6" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<vertices id="mesh-cube-vertices">
<input semantic="POSITION" source="#mesh-cube-positions"/>
</vertices>
<triangles count="12">
<input semantic="VERTEX" source="#mesh-cube-vertices" offset="0"/>
<input semantic="NORMAL" source="#mesh-cube-normals" offset="1"/>
<p>1 0 2 0 0 0 3 1 6 1 2 1 7 2 4 2 6 2 5 3 0 3 4 3 6 4 0 4 2 4 3 5 5 5 7 5 1 0 3 0 2 0 3 1 7 1 6 1 7 2 5 2 4 2 5 3 1 3 0 3 6 4 4 4 0 4 3 5 1 5 5 5</p>
</triangles>
</mesh>
</geometry>
</library_geometries>
<library_visual_scenes>
<visual_scene id="Scene" name="Scene">
<node>
<matrix sid="transform">0.35 0 0 0 0 0.4 0 0 0 0 1 0 0 0 0 1</matrix>
<instance_geometry url="#mesh-cube">
<bind_material>
<technique_common>
<instance_material symbol="material" target="#material-cube"/>
</technique_common>
</bind_material>
</instance_geometry>
</node>
</visual_scene>
</library_visual_scenes>
<scene>
<instance_visual_scene url="#Scene"/>
</scene>
</COLLADA>

0 comments on commit 89b1157

Please sign in to comment.