std::string readFromStream(std::istream& in) { in.unsetf(std::ios::skipws) ; std::string return_info(std::istreambuf_iterator<char>(in.rdbuf()), std::istreambuf_iterator<char>()) ; return return_info ; }
//Load materials from MTL source stream. Returns Model object with materials //TODO: think about splitting this function. ModelPtr loadMtl(std::istream& source, Manager& inManager){ if(!source.good()) throw std::runtime_error("OBJModelLoader: stream is in bad condition. Can't read data."); //do not eat spaces (we will eat them manually) source.unsetf(std::istream::skipws); ModelPtr model(new Model()); MaterialPtr lastMaterial; findNextToken(source); while(source.good()){ std::string command = getNextToken(source); eatSpaces(source); if(!source.good()) break; if(command == "newmtl"){ //new material command std::string matName = getNextToken(source); //get next word(name) //if already taken data for some material if(lastMaterial){ //add new mesh model->mMeshes.push_back(MeshPtr(new Mesh())); //set current material to new mesh model->mMeshes.back()->mMaterial = lastMaterial; lastMaterial.reset(); } lastMaterial = MaterialPtr(new Material()); lastMaterial->mName = matName; } else if(!lastMaterial){ //no newmtl directive before first commands std::cerr << "OBJModelLoader: ERROR: newmtl directive should stand before any other directives" << std::endl; } else if(command[0] == 'K' && command.size() == 2){ //Ka, Kd or Ks float r = 0.0f, g = -1.0, b; source >> r; eatSpaces(source); if(isspace(source.peek())) g = b = r; else{ source >> g; eatSpaces(source); source >> b; } Color newColor(r, g, b); switch(command[1]){ case 'a': //Ka lastMaterial->mAmbient = newColor; break; case 'd': //Kd lastMaterial->mDiffuse = newColor; break; case 's': //Ks lastMaterial->mSpecular = newColor; break; case 'e': //Ke lastMaterial->mEmissive = newColor; default: //error //throw std::runtime_error("OBJModelLoader: unknown directive in mtl file"); break; } } //TODO: delete copy-paste code (textures must be handled in one common way) else if(command.find("map_K") != std::string::npos){ //map_Kd, map_Ka, map_Ks