Example #1
0
 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