in roboschool/cpp-household/random-world-tools.cpp [12:54]
shared_ptr<Material> World::texture_from_file_cached(const std::string& texid)
{
if (texid.empty()) return shared_ptr<Material>();
if (!textures_cache) textures_cache.reset(new MaterialNamespace);
auto f = textures_cache->name2mtl.find(texid);
if (f!=textures_cache->name2mtl.end())
return f->second;
shared_ptr<Material> mat(new Material(texid));
mat->diffuse_color = 0x0000FF; // default color for failed-to-load materials
if (texid[0]=='#') { // color, like "#FF0000" for red
assert("color should be #rrggbb" && texid.size()==7);
int parsed = sscanf(texid.substr(1).c_str(), "%x", &mat->diffuse_color);
assert(parsed==1);
} else try {
std::string mtl_fn;
std::string mtl_name;
std::string::size_type f = texid.find(":");
if (f==std::string::npos) {
mtl_fn = texid;
} else {
mtl_fn = texid.substr(0, f);
mtl_name = texid.substr(f+1);
}
shared_ptr<ShapeDetailLevels> dummy(new ShapeDetailLevels);
load_model(dummy, mtl_fn, 1.0, false);
assert(!dummy->materials->name2mtl.empty());
if (mtl_name.empty()) {
mat = dummy->materials->name2mtl.begin()->second;
} else {
auto i = dummy->materials->name2mtl.find(mtl_name);
if (i==dummy->materials->name2mtl.end())
throw std::runtime_error("no '" + mtl_name + "' inside '" + mtl_fn + "'");
mat = i->second;
}
} catch (const std::exception& e) {
fprintf(stderr, "material file '%s' cannot be loaded: %s\n", texid.c_str(), e.what());
}
textures_cache->name2mtl[texid] = mat;
return mat;
}