Пример #1
0
    void ParseLine( const char* line )
    {
        m_line = line;
        SkipSpace();

        switch(*(m_line++))
        {
        case 'f':
            if (isspace(*(m_line++)))
            {
                ParseFace();
            }
            break;
        case 'v':
        {
            char ch = *(m_line++);
            switch (ch)
            {
            case 'n':
            {
                ParseVec3(m_normals);
                return;
            }
            case 't':
            {
                ParseVec2(m_uvs);
                return;
            }
            default:
                if (isspace(ch))
                {
                    ParseVec3(m_positions);
                }
                return;
            }
        }
        }
    }
Пример #2
0
ObjModel::ObjModel(const std::string& filePath)
{
	// standardise dir seperators
	std::string filePathStd = std::string(filePath);
	std::replace(filePathStd.begin(), filePathStd.end(), '\\', '/');

	// asd/asd/asd/asd/asd/asd/file.obj
	auto tokens = SplitString(filePathStd, '/');
	std::string fileName = tokens[tokens.size() - 1];
	std::string workingDir = filePathStd.substr(0, filePathStd.size() - fileName.size());


	std::ifstream file;
	file.open((workingDir + "/" + fileName).c_str());
	
	int curMaterialIndex = 0;
	std::string line;
	if (file.is_open())
	{
		while (file.good())
		{
			getline(file, line);

			unsigned int lineLength = line.length();
			if (lineLength < 2)
				continue;

			const char* lineCStr = line.c_str();

			switch (lineCStr[0])
			{
			case 'v': // "v?" => vertex
			{
				switch (lineCStr[1])
				{
				case 't': // ? == 't' => vertex texture / uv coords
				{
#define TEMP_SSCANF // ~5.5 secs
//#define TEMP_SPLIT // ~10 secs
//#define TEMP_STREAM // ~7.5 secs

#ifdef TEMP_SSCANF
					glm::vec2 vt;
					sscanf_s(lineCStr, "vt %f %f", &vt.x, &vt.y);
					textures.push_back(vt);
#endif // SSCANF
#ifdef TEMP_SPLIT
					textures.push_back(ParseVec2(line));
#endif // TEMP_SPLIT
#ifdef TEMP_STREAM
					std::istringstream issvt(line.substr(2));
					glm::vec2 vt;
					issvt >> vt.x;
					issvt >> vt.y;
					textures.push_back(vt);
#endif // TEMP_STREAM
					break;
				}
				case 'n': // ? == 'n' => vertex normal
				{
#ifdef TEMP_SSCANF
					glm::vec3 vn;
					sscanf_s(lineCStr, "vn %f %f %f", &vn.x, &vn.y, &vn.z);
					normals.push_back(vn);
#endif // SSCANF
#ifdef TEMP_SPLIT
					normals.push_back(ParseVec3(line));
#endif // TEMP_SPLIT
#ifdef TEMP_STREAM
					std::istringstream issvt(line.substr(2));
					glm::vec3 vn;
					issvt >> vn.x;
					issvt >> vn.y;
					issvt >> vn.z;
					normals.push_back(vn);
#endif // TEMP_STREAM
					break;
				}
				case '\t': // ? == ' ' => vertex
				case ' ':
				{
#ifdef TEMP_SSCANF
					glm::vec3 v;
					sscanf_s(lineCStr, "v %f %f %f", &v.x, &v.y, &v.z);
					positions.push_back(v);
#endif // SSCANF
#ifdef TEMP_SPLIT
					positions.push_back(ParseVec3(line));
#endif // TEMP_SPLIT
#ifdef TEMP_STREAM
					std::istringstream issvt(line.substr(2));
					glm::vec3 v;
					issvt >> v.x;
					issvt >> v.y;
					issvt >> v.z;
					positions.push_back(v);
#endif // TEMP_STREAM
					break;
				}
				}
				break;
			}
			case 'f': // 'f' => face
			{
				CreateFace(curMaterialIndex, line);
				break;
			}
			case 'm': // 'm' => material template lib 
			{
				if (lineCStr[1] != 't')
					break;
				char buffer[BUFSIZ];
				sscanf_s(lineCStr, "mtllib %s", &buffer);
				std::string mtlFileName = std::string(buffer);
				//std::string mtlFileName = SplitString(line, ' ')[1];
				std::vector<Material*> mats = LoadMaterials(workingDir, mtlFileName);
				materials.insert(std::end(materials), std::begin(mats), std::end(mats));
				break;
			}
			case 'u': // 'u' => usemtl
			{
				if (lineCStr[1] != 's')
					break;
				std::string mtlName = SplitString(line, ' ')[1];
				for (int i = 0; i < materials.size(); i++)
				{
					if (materials[i]->name == mtlName)
					{
						curMaterialIndex = i;
						break;
					}
				}
				break;
			}
			};
		}
	}
	else
	{