Ejemplo n.º 1
0
	static inline pugi::xml_node& currentMaterial() {
		return currentMaterial(nullptr);
	}
Ejemplo n.º 2
0
//MTL PARSER INSPIRED FROM KIXOR.NET "objloader" (http://www.kixor.net/dev/objloader/)
bool ccMaterialSet::ParseMTL(QString path, const QString& filename, ccMaterialSet &materials, QStringList& errors)
{
	//open mtl file
	QString fullPathFilename = path + QString('/') + filename;
	QFile file(fullPathFilename);
	if (!file.open(QFile::ReadOnly))
	{
		errors << QString("Error reading file: %1").arg(filename);
		return false;
	}

	//update path (if the input filename has already a relative path)
	path = QFileInfo(fullPathFilename).absolutePath();
	
	QTextStream stream(&file);

	QString currentLine = stream.readLine();
	unsigned currentLineIndex = 0;
	ccMaterial::Shared currentMaterial(0);
	while( !currentLine.isNull() )
	{
		++currentLineIndex;

		QStringList tokens = currentLine.split(QRegExp("\\s+"),QString::SkipEmptyParts);

		//skip comments & empty lines
		if( tokens.empty() || tokens.front().startsWith('/',Qt::CaseInsensitive) || tokens.front().startsWith('#',Qt::CaseInsensitive) )
		{
			currentLine = stream.readLine();
			continue;
		}

		//start material
		if (tokens.front() == "newmtl")
		{
			//push the previous material (if any)
			if (currentMaterial)
			{
				materials.addMaterial(currentMaterial);
				currentMaterial = ccMaterial::Shared(0);
			}

			// get the name
			QString materialName = currentLine.mid(7).trimmed(); //we must take the whole line! (see OBJ filter)
			if (materialName.isEmpty())
				materialName = "undefined";
			currentMaterial = ccMaterial::Shared(new ccMaterial(materialName));

		}
		else if (currentMaterial) //we already have a "current" material
		{
			//ambient
			if (tokens.front() == "Ka")
			{
				if (tokens.size() > 3)
				{
					ccColor::Rgbaf ambient(	tokens[1].toFloat(),
											tokens[2].toFloat(),
											tokens[3].toFloat(),
											1.0f);
					currentMaterial->setAmbient(ambient);
				}
			}

			//diff
			else if (tokens.front() == "Kd")
			{
				if (tokens.size() > 3)
				{
					ccColor::Rgbaf diffuse(	tokens[1].toFloat(),
											tokens[2].toFloat(),
											tokens[3].toFloat(),
											1.0f);
					currentMaterial->setDiffuse(diffuse);
				}
			}

			//specular
			else if (tokens.front() == "Ks")
			{
				if (tokens.size() > 3)
				{
					ccColor::Rgbaf specular(tokens[1].toFloat(),
											tokens[2].toFloat(),
											tokens[3].toFloat(),
											1.0f);
					currentMaterial->setSpecular(specular);
				}
			}
			//shiny
			else if (tokens.front() == "Ns")
			{
				if (tokens.size() > 1)
					currentMaterial->setShininess(tokens[1].toFloat());
			}
			//transparent
			else if (tokens.front() == "d" || tokens.front() == "Tr")
			{
				if (tokens.size() > 1)
					currentMaterial->setTransparency(tokens[1].toFloat());
			}
			//reflection
			else if (tokens.front() == "r")
			{
				//ignored
				//if (tokens.size() > 1)
				//	currentMaterial->reflect = tokens[1].toFloat();
			}
			//glossy
			else if (tokens.front() == "sharpness")
			{
				//ignored
				//if (tokens.size() > 1)
				//	currentMaterial->glossy = tokens[1].toFloat();
			}
			//refract index
			else if (tokens.front() == "Ni")
			{
				//ignored
				//if (tokens.size() > 1)
				//	currentMaterial->refract_index = tokens[1].toFloat();
			}
			// illumination type
			else if (tokens.front() == "illum")
			{
				//ignored
			}
			// texture map
			else if (tokens.front() == "map_Ka"
					|| tokens.front() == "map_Kd"
					|| tokens.front() == "map_Ks")
			{
				//DGM: in case there's hidden or space characters at the beginning of the line...
				int shift = currentLine.indexOf("map_K",0);
				QString textureFilename = (shift + 7 < currentLine.size() ? currentLine.mid(shift+7).trimmed() : QString());
				QString fullTexName = path + QString('/') + textureFilename;
				if (!currentMaterial->loadAndSetTexture(fullTexName))
				{
					errors << QString("Failed to load texture file: %1").arg(fullTexName);
				}
			}
			else
			{
				errors << QString("Unknown command '%1' at line %2").arg(tokens.front()).arg(currentLineIndex);
			}
		}

		currentLine = stream.readLine();
	}

	file.close();

	//don't forget to push the last material!
	if (currentMaterial)
		materials.addMaterial(currentMaterial);

	return true;
}