示例#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
LightEnv::LightEnv( const std::string& envFilename )
	: m_fLightAttenuation(40.0f)
{
	std::ifstream fileStream(envFilename.c_str());
	if(!fileStream.is_open())
		throw std::runtime_error("Could not find the mesh file.");

	TiXmlDocument theDoc;

	fileStream >> theDoc;
	fileStream.close();

	if(theDoc.Error())
		throw std::runtime_error(theDoc.ErrorDesc());

	TiXmlHandle docHandle(&theDoc);

	const TiXmlElement *pRootNode = docHandle.FirstChild("lightenv").ToElement();

	if(!pRootNode)
		throw std::runtime_error("The root node must be a 'lightenv' element.");

	pRootNode->QueryFloatAttribute("atten", &m_fLightAttenuation);
	m_fLightAttenuation = 1.0f / (m_fLightAttenuation * m_fLightAttenuation);

	const TiXmlElement *pSunNode = docHandle.FirstChild("lightenv").FirstChild("sun").ToElement();

	if(!pSunNode)
		throw std::runtime_error("There must be a 'lightenv' element that has a 'sun' element as a child.");

	float timerTime = 0;
	if(pSunNode->QueryFloatAttribute("time", &timerTime) != TIXML_SUCCESS)
		throw std::runtime_error("'sun' elements must have a 'time' attribute that is a float.");

	m_sunTimer = Framework::Timer(Framework::Timer::TT_LOOP, timerTime);

	LightVector ambient;
	LightVector light;
	LightVector background;
	MaxIntensityVector maxIntensity;

	for(const TiXmlElement *pKeyElem = pSunNode->FirstChildElement("key");
		pKeyElem;
		pKeyElem = pKeyElem->NextSiblingElement("key"))
	{
		float keyTime = 0;
		if(pKeyElem->QueryFloatAttribute("time", &keyTime) != TIXML_SUCCESS)
			throw std::runtime_error("'key' elements must have a 'time' attribute that is a float.");
		//Convert from hours to normalized time.
		keyTime = keyTime / 24.0f;

		std::string strVec4;
		if(pKeyElem->QueryStringAttribute("ambient", &strVec4) != TIXML_SUCCESS)
			throw std::runtime_error("'key' elements must have an 'ambient' attribute.");
		ambient.push_back(LightData(ParseVec4(strVec4), keyTime));

		if(pKeyElem->QueryStringAttribute("intensity", &strVec4) != TIXML_SUCCESS)
			throw std::runtime_error("'key' elements must have a 'intensity' attribute.");
		light.push_back(LightData(ParseVec4(strVec4), keyTime));

		if(pKeyElem->QueryStringAttribute("background", &strVec4) != TIXML_SUCCESS)
			throw std::runtime_error("'key' elements must have a 'background' attribute.");
		background.push_back(LightData(ParseVec4(strVec4), keyTime));

		maxIntensity.push_back(MaxIntensityData(0.0f, keyTime));
		if(pKeyElem->QueryFloatAttribute("max-intensity", &maxIntensity.back().first) != TIXML_SUCCESS)
			throw std::runtime_error("'key' elements must have a 'max-intensity' attribute that is a float.");
	}

	if(ambient.empty())
		throw std::runtime_error("'sun' element must have at least one 'key' element child.");

	m_ambientInterpolator.SetValues(ambient);
	m_sunlightInterpolator.SetValues(light);
	m_backgroundInterpolator.SetValues(background);
	m_maxIntensityInterpolator.SetValues(maxIntensity);

	const TiXmlElement *pLightNode = docHandle.FirstChild("lightenv").FirstChild("light").ToElement();
	for(; pLightNode; pLightNode = pLightNode->NextSiblingElement("light"))
	{
		if(m_lightPos.size() + 1 == MAX_NUMBER_OF_LIGHTS)
			throw std::runtime_error("Too many lights specified.");

		float lightTime = 0;
		if(pLightNode->QueryFloatAttribute("time", &lightTime) != TIXML_SUCCESS)
			throw std::runtime_error("'light' elements must have a 'time' attribute that is a float.");

		m_lightTimers.push_back(Framework::Timer(Framework::Timer::TT_LOOP, lightTime));

		std::string strVec4;
		if(pLightNode->QueryStringAttribute("intensity", &strVec4) != TIXML_SUCCESS)
			throw std::runtime_error("'light' elements must have an 'intensity' attribute.");
		m_lightIntensity.push_back(ParseVec4(strVec4));

		std::vector<glm::vec3> posValues;
		for(const TiXmlElement *pKeyElem = pLightNode->FirstChildElement("key");
			pKeyElem;
			pKeyElem = pKeyElem->NextSiblingElement("key"))
		{
			posValues.push_back(ParseVec3(pKeyElem->GetText()));
		}

		if(posValues.empty())
			throw std::runtime_error("'light' elements must have at least one 'key' element child.");

		m_lightPos.push_back(LightInterpolator());
		m_lightPos.back().SetValues(posValues);
	}
}
示例#3
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
	{