GLboolean store_binary_material(const aiScene* scene, const aiMesh* mesh, std::string& material_name) { aiMaterial* new_material = scene->mMaterials[mesh->mMaterialIndex]; std::string material_path; std::string diffuse_name; std::string specular_name; aiString name; new_material->Get(AI_MATKEY_NAME,name); material_name = name.data; if (material_name.empty()) { std::cout << __FILE__ << ":" << __LINE__ << ": " << "ERROR: Cannot store material with empty name!" << std::endl; errorlogger("ERROR: Cannot store material with empty name!"); return false; } diffuse_name = load_material_texture(new_material, aiTextureType_DIFFUSE); specular_name = load_material_texture(new_material, aiTextureType_SPECULAR); material_path = Utility_vars::folder_path + MATERIAL_DATA_PATH + material_name + ".mat"; if (file_exists(material_path)) { std::cout << __FILE__ << ":" << __LINE__ << ": " << "ERROR: Failed to store binary material, target file exists: " << material_path << std::endl; errorlogger("ERROR: Failed to store binary material, target file exists: ", material_path.c_str()); return false; } std::ofstream contentf (material_path.c_str(), std::ios::binary); if (!contentf.is_open()){ std::cout << __FILE__ << ":" << __LINE__ << ": " << "FATAL ERROR: Failed to open content file for storing material data: " << material_path << std::endl; errorlogger("FATAL ERROR: Failed to open content file for storing material data: ", material_path.c_str()); exit(EXIT_FAILURE); } if (!diffuse_name.empty()){ contentf.write(reinterpret_cast<const char *>(&Utility_consts::TRUE_BOOL), sizeof(GLuint)); write_string_to_binary_file(contentf, diffuse_name); } else{ contentf.write(reinterpret_cast<const char *>(&Utility_consts::FALSE_BOOL), sizeof(GLuint)); } if (!specular_name.empty()){ contentf.write(reinterpret_cast<const char *>(&Utility_consts::TRUE_BOOL), sizeof(GLuint)); write_string_to_binary_file(contentf, specular_name); } else{ contentf.write(reinterpret_cast<const char *>(&Utility_consts::FALSE_BOOL), sizeof(GLuint)); } contentf.close(); return true; }
void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToStateSetMap& materialToStateSetMap) const { if (_fixBlackMaterials) { // hack to fix Maya exported models that contian all black materials. int numBlack = 0; int numNotBlack = 0; obj::Model::MaterialMap::iterator itr; for(itr = model.materialMap.begin(); itr != model.materialMap.end(); ++itr) { obj::Material& material = itr->second; if (material.ambient==osg::Vec4(0.0f,0.0f,0.0f,1.0f) && material.diffuse==osg::Vec4(0.0f,0.0f,0.0f,1.0f)) { ++numBlack; } else { ++numNotBlack; } } if (numNotBlack==0 && numBlack!=0) { for(itr = model.materialMap.begin(); itr != model.materialMap.end(); ++itr) { obj::Material& material = itr->second; if (material.ambient==osg::Vec4(0.0f,0.0f,0.0f,1.0f) && material.diffuse==osg::Vec4(0.0f,0.0f,0.0f,1.0f)) { material.ambient.set(0.3f,0.3f,0.3f,1.0f); material.diffuse.set(1.0f,1.0f,1.0f,1.0f); } } } } for(obj::Model::MaterialMap::iterator itr = model.materialMap.begin(); itr != model.materialMap.end(); ++itr) { obj::Material& material = itr->second; osg::ref_ptr< osg::StateSet > stateset = new osg::StateSet; bool isTransparent = false; // handle material colors // http://java3d.j3d.org/utilities/loaders/obj/sun.html if (material.illum != 0) { osg::Material* osg_material = new osg::Material; stateset->setAttribute(osg_material); osg_material->setAmbient(osg::Material::FRONT_AND_BACK,material.ambient); osg_material->setDiffuse(osg::Material::FRONT_AND_BACK,material.diffuse); osg_material->setEmission(osg::Material::FRONT_AND_BACK,material.emissive); if (material.illum == 2) { osg_material->setSpecular(osg::Material::FRONT_AND_BACK,material.specular); } else { osg_material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,1)); } osg_material->setShininess(osg::Material::FRONT_AND_BACK,(material.Ns/1000.0f)*128.0f ); // note OBJ shiniess is 0..1000. if (material.ambient[3]!=1.0 || material.diffuse[3]!=1.0 || material.specular[3]!=1.0|| material.emissive[3]!=1.0) { osg::notify(osg::INFO)<<"Found transparent material"<<std::endl; isTransparent = true; } } // handle textures enum TextureUnit { TEXTURE_UNIT_KD = 0, TEXTURE_UNIT_OPACITY }; load_material_texture( model, material, stateset.get(), material.map_Kd, TEXTURE_UNIT_KD ); load_material_texture( model, material, stateset.get(), material.map_opacity, TEXTURE_UNIT_OPACITY ); if (isTransparent) { stateset->setMode(GL_BLEND, osg::StateAttribute::ON); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } materialToStateSetMap[material.name] = stateset.get(); } }
void ReaderWriterOBJ::buildMaterialToStateSetMap(obj::Model& model, MaterialToStateSetMap& materialToStateSetMap, ObjOptionsStruct& localOptions, const Options* options) const { if (localOptions.fixBlackMaterials) { // hack to fix Maya exported models that contian all black materials. int numBlack = 0; int numNotBlack = 0; obj::Model::MaterialMap::iterator itr; for(itr = model.materialMap.begin(); itr != model.materialMap.end(); ++itr) { obj::Material& material = itr->second; if (material.ambient==osg::Vec4(0.0f,0.0f,0.0f,1.0f) && material.diffuse==osg::Vec4(0.0f,0.0f,0.0f,1.0f)) { ++numBlack; } else { ++numNotBlack; } } if (numNotBlack==0 && numBlack!=0) { for(itr = model.materialMap.begin(); itr != model.materialMap.end(); ++itr) { obj::Material& material = itr->second; if (material.ambient==osg::Vec4(0.0f,0.0f,0.0f,1.0f) && material.diffuse==osg::Vec4(0.0f,0.0f,0.0f,1.0f)) { material.ambient.set(0.3f,0.3f,0.3f,1.0f); material.diffuse.set(1.0f,1.0f,1.0f,1.0f); } } } } for(obj::Model::MaterialMap::iterator itr = model.materialMap.begin(); itr != model.materialMap.end(); ++itr) { obj::Material& material = itr->second; osg::ref_ptr< osg::StateSet > stateset = new osg::StateSet; bool isTransparent = false; // handle material colors // http://java3d.j3d.org/utilities/loaders/obj/sun.html if (material.illum != 0) { osg::Material* osg_material = new osg::Material; stateset->setAttribute(osg_material); osg_material->setName(material.name); osg_material->setAmbient(osg::Material::FRONT_AND_BACK,material.ambient); osg_material->setDiffuse(osg::Material::FRONT_AND_BACK,material.diffuse); osg_material->setEmission(osg::Material::FRONT_AND_BACK,material.emissive); if (material.illum == 2) { osg_material->setSpecular(osg::Material::FRONT_AND_BACK,material.specular); } else { osg_material->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,1)); } osg_material->setShininess(osg::Material::FRONT_AND_BACK,(material.Ns/1000.0f)*128.0f ); // note OBJ shiniess is 0..1000. if (material.ambient[3]!=1.0 || material.diffuse[3]!=1.0 || material.specular[3]!=1.0|| material.emissive[3]!=1.0) { OSG_INFO<<"Found transparent material"<<std::endl; isTransparent = true; } } // If the user has explicitly set the required texture type to unit map via the options // string, then we load ONLY those textures that are in the map. if(localOptions.textureUnitAllocation.size()>0) { for(unsigned int i=0;i<localOptions.textureUnitAllocation.size();i++) { // firstly, get the option set pair int unit = localOptions.textureUnitAllocation[i].first; obj::Material::Map::TextureMapType type = localOptions.textureUnitAllocation[i].second; // secondly, see if this texture type (e.g. DIFFUSE) is one of those in the material int index = -1; for(unsigned int j=0;j<material.maps.size();j++) { if(material.maps[j].type == type) { index = (int) j; break; } } if(index>=0) load_material_texture( model, material.maps[index], stateset.get(), unit, options ); } } // If the user has set no options, then we load them up in the order contained in the enum. This // latter method is an attempt not to break user's existing code else { int unit = 0; for(int i=0;i<(int) obj::Material::Map::UNKNOWN;i++) // for each type { obj::Material::Map::TextureMapType type = (obj::Material::Map::TextureMapType) i; // see if this texture type (e.g. DIFFUSE) is one of those in the material int index = -1; for(unsigned int j=0;j<material.maps.size();j++) { if(material.maps[j].type == type) { index = (int) j; break; } } if(index>=0) { load_material_texture( model, material.maps[index], stateset.get(), unit, options ); unit++; } } } if (isTransparent) { stateset->setMode(GL_BLEND, osg::StateAttribute::ON); stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); } materialToStateSetMap[material.name] = stateset.get(); } }