shared_ptr World::texture_from_file_cached()

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;
}