예제 #1
0
  /**
   * Loads the specified file, then validates.
   */
  bool OBJModel::loadFile(const std::string& filename) {
    writeToLog(MessageLevel::INFO, "Loading model from file \"%s\"\n", filename.c_str());
    valid = false;
    
    path p(filename);
    uint32_t fileLine = 0;
    if (exists(p) && is_regular_file(p)) {
      std::ifstream file(p.generic_string());

      vertices.clear();
      textureCoords.clear();
      normals.clear();
      faces.clear();

      vertices.push_back(Vector3(0.0f, 0.0f, 0.0f));
      textureCoords.push_back(Vector2(0.0f, 0.0f));
      normals.push_back(Vector3(0.0f, 0.0f, 0.0f));

      do {
        std::string line;
        std::getline(file, line);
        fileLine++;
        StringTokenizer tokens(line, ' ');

        if (tokens.getTokenCount() > 0) {
          std::string type = tokens.getToken(0);
          if (type.compare("v") == 0) {
            Vector3 vertex = vector3FromTokens(tokens.getToken(1),
                                               tokens.getToken(2),
                                               tokens.getToken(3));

            vertices.push_back(vertex);
          } else if (type.compare("vt") == 0) {
            Vector2 texCoord = vector2FromTokens(tokens.getToken(1),
                                                 tokens.getToken(2));

            textureCoords.push_back(texCoord);
          } else if (type.compare("vn") == 0) {
            Vector3 normal = vector3FromTokens(tokens.getToken(1),
                                               tokens.getToken(2),
                                               tokens.getToken(3));

            normals.push_back(normal);
          } else if (type.compare("f") == 0) {
            OBJFace face;

            for (uint32_t i = 1; i < tokens.getTokenCount(); i++) {
              StringTokenizer faceTokens(tokens.getToken(i), '/');

              int32_t v = 0;
              int32_t vt = 0;
              int32_t vn = 0;

              try {
                v = std::stoi(faceTokens.getToken(0));
                if (v < 0) {
                  v += vertices.size();
                }
              } catch (std::exception&) {
                v = 0;
              }

              try {
                vt = std::stoi(faceTokens.getToken(1));
                if (vt < 0) {
                  vt += textureCoords.size();
                }
              } catch (std::exception&) {
                vt = 0;
              }

              try {
                vn = std::stoi(faceTokens.getToken(2));
                if (vn < 0) {
                  vn += normals.size();
                }
              } catch (std::exception&) {
                vn = 0;
              }

              face.push(v, vt, vn);
            }
            
            //  We only support triangulated models.
            if (face.getTripletCount() > 3) {
              writeToLog(MessageLevel::ERROR, "Malformed face on line %d in \"%s\":  Too many points, only triangles are supported.\n", fileLine, filename.c_str());
              return false;
            }
            
            faces.push_back(face);
          } else {
            //  Currently a no-op.
          }
        }
      } while(!file.eof() && file.good());
    } else {
      writeToLog(MessageLevel::ERROR, "Could not find file \"%s\".\n", filename.c_str());
      return false;
    }

    return validate();
  }
void VBOWFModel::Tokenise_Data(std::string input)
{
    float tempfloat[3];         //temporary float array of 3
    StringTokens tokens(input,' ');


    if(tokens.First_token()=="v")              //if vertices
    {
        tokens.Next_token();

        tempfloat[0] = (float)atof(tokens.Next_token().c_str()); //x value

        tempfloat[1] = (float)atof(tokens.Next_token().c_str()); //y value

        tempfloat[2] = (float)atof(tokens.Next_token().c_str()); //z value

        verts.push_back(Vec3f(tempfloat[0],tempfloat[1],tempfloat[2]));
    }
    else if(tokens.First_token()=="vn")        //if normals
    {
        tokens.Next_token();
        tempfloat[0] = (float)atof(tokens.Next_token().c_str()); //x value

        tempfloat[1] = (float)atof(tokens.Next_token().c_str()); //y value

        tempfloat[2] = (float)atof(tokens.Next_token().c_str()); //z value

        norms.push_back(Vec3f(tempfloat[0],tempfloat[1],tempfloat[2]));
    }
    else if(tokens.First_token()=="vt")        //if texture coords
    {
        tokens.Next_token();
        tempfloat[0] = (float)atof(tokens.Next_token().c_str()); //x value

        tempfloat[1] = (float)atof(tokens.Next_token().c_str()); //y value

        tempfloat[2] = (float)atof(tokens.Next_token().c_str()); //z value

        tex.push_back(Vec2f(tempfloat[0],tempfloat[1]));
    }
    else if(tokens.First_token()=="f")         //if face
    {
        tokens.Next_token();
        Vec3f temp;
        for(int i=0; i<3; i++)      //get 3 vert indexes, text coord index, normals index
        {
            StringTokens faceTokens(tokens.Next_token(),'/');

            m_Vindices.push_back(atoi(faceTokens.Next_token().c_str())-1);    //store vertex index

            m_Tindices.push_back(atoi(faceTokens.Next_token().c_str())-1);

            m_Nindices.push_back(atoi(faceTokens.Next_token().c_str())-1);
        }
    }
    else if(tokens.First_token()=="mtllib")        //if material lib
    {
        string mtl = "Model/";      //mtl file location
        string image = "textures/wdworld/"; //image file location
        string temp2;
        tokens.Next_token();
        mtl.append(tokens.Next_token());          //add it to the location
        ifstream material(mtl.c_str()); //create input filestream for MTL

        if(material)        //if material exists
        {
            while(std::getline(material, temp2)) //tokenize MTL
            {
                istringstream matName(temp2);
                getline(matName,temp2); //get image name
                image.append(temp2);    //add it to the location
                mtlName.push_back(image);   //store it
                image = "textures/wdworld/";    //reset image to only location
            }
            m_texture = Texture(mtlName.back());
            if(!(m_texture.LoadTexture()))//if loaded succesfully
            {
                cout << "File DNE" << endl;
            }
        }
        else                //if material DNE
        {
            cout << "material file " << temp2 << " DNE" << endl;
        }
    }
}