Esempio n. 1
0
//Loads an OBJ file into this mesh
//Does not currently account for textures
void Mesh::loadOBJ(std::string fileName) {
	std::vector<glm::vec3> vertices;
	std::vector<glm::vec2> uvs;
	std::vector<glm::vec3> normals;

	std::ifstream objFile(fileName, std::ios::in);
	if (!objFile.is_open()) {
		std::cout << "Failed to open the file " << fileName << std::endl;
	}
	
	std::string line;
	
	while (getline(objFile,line)) {
		if (line.length() == 0) {	//Line was empty, for some reason
			continue;
		}

		std::stringstream lineStream(line);	//Possible performance issues
		std::string lineType;
		
		lineStream >> lineType;

		if (lineType == "v") {	//We're dealing with a vertex
			float x,y,z;
			lineStream >> x >> y >> z;
			vertices.push_back(glm::vec3(x,y,z));
		}
		else if (lineType == "vt") {	//"" UV
Esempio n. 2
0
void NewAreaDialog::confirm() {
	name = nameEdit->text();
	tile = tileEdit->text();
	obj = objEdit->text();
	width = widthEdit->text().toInt();
	height = heightEdit->text().toInt();
	
	if(name.isEmpty() || name.isNull()) {
		QMessageBox::information(this, "Error", "Name is invalid");
		return;
	}
	
	QFile tileFile(tile);
	tileFile.open(QFile::ReadOnly);
	if(!tileFile.exists() || !tileFile.isOpen()) {
		QMessageBox::information(this, "Error", "Terrain sheet is invalid");
		return;
	}
	
	QFile objFile(obj);
	objFile.open(QFile::ReadOnly);
	if(!objFile.exists() || !objFile.isOpen()) {
		QMessageBox::information(this, "Error", "Object sheet is invalid");
		return;
	}
	
	accept();
}
Esempio n. 3
0
void GeometryLoader::loadFromFile(const std::string& filename)
{
	std::ifstream objFile(filename);
	if (objFile.is_open())
	{
		processFile(objFile);
		objFile.close();
		printStatistics(filename);
	}
	else
	{
		std::cout << "ERROR: cannot open a file\n";
	}
}
Esempio n. 4
0
void Mesh::writeObj(Mesh mesh, string filename)
{
	std::ofstream objFile(filename);

	for (const auto& v : mesh.vertex) {
		//objFile << "v " << v.position[0] << " " << v.position[1] << " " << v.position[2] << std::endl;
		objFile << "v " << v.position[0] << " " << v.position[1] << " " << v.position[2] << " " << v.color[0] << " " << v.color[1] << " " << v.color[2] << " " << std::endl;
	}

	for (const auto& v : mesh.tvi) {
		objFile << "f " << v[0]+1 << " " << v[1]+1 << " " << v[2]+1 << std::endl;
	}
	objFile.close();
	return;

	// obj starts counting triangles at 1
}
Esempio n. 5
0
WaveFrontObj WaveFrontUtils::LoadObj(const char * path)
{
	WaveFrontObj obj;
	ifstream objFile(path,std::ifstream::in);
	if(objFile.is_open()){ // Verifica se arquivo esta aberto
		while(objFile.good() && !objFile.eof()){
			string linha;
			getline(objFile, line);
			if(linha.front() == 'v'){ // linha de vertex
				vector<float> vertex = Utils::SplitStringToFloat(' ', linha);
				obj.addVertex(vertex);
			}
		}
		objFile.close();
	}
	return obj;
}
Esempio n. 6
0
/// Yus.
bool Mesh::SaveObj(String path)
{
	if (!path.Contains(".obj"))
		path = path + ".obj";
	File objFile(path);
	bool ok = objFile.OpenForWritingText();
	if (!ok)
		return false;
	std::fstream & fstream = objFile.GetStream();
	fstream<<"o "<<name;
	for (int i = 0; i < vertices.Size(); ++i)
	{
		Vector3f & v = vertices[i];
		fstream<<"\nv "<<v;
	}
	for (int i = 0; i < uvs.Size(); ++i)
	{
		Vector2f & uv = uvs[i];
		fstream<<"\nvt "<<uv;
	}
	for (int i = 0; i < normals.Size(); ++i)
	{
		Vector3f & n = normals[i];
		fstream<<"\nvn "<<n;
	}
	for (int i = 0; i < faces.Size(); ++i)
	{
		MeshFace & f = faces[i];
		fstream<<"\nf";
		for (int i = 0; i < f.vertices.Size(); ++i)
		{
			fstream<<" "<<(f.vertices[i]+1);
			if (f.normals.Size() || f.uvs.Size())
				fstream<<"/";
			if (f.uvs.Size())
				fstream<<(f.uvs[i]+1);
			if (f.normals.Size())
				fstream<<"/"<<(f.normals[i]+1);
		}
	}
	objFile.Close();
	return true;
}
Esempio n. 7
0
void OBJBaker::bakeOBJ() {
    // Read the OBJ file
    QFile objFile(_originalModelFilePath);
    if (!objFile.open(QIODevice::ReadOnly)) {
        handleError("Error opening " + _originalModelFilePath + " for reading");
        return;
    }

    QByteArray objData = objFile.readAll();

    bool combineParts = true; // set true so that OBJReader reads material info from material library
    OBJReader reader;
    auto geometry = reader.readOBJ(objData, QVariantHash(), combineParts, _modelURL);

    // Write OBJ Data as FBX tree nodes
    createFBXNodeTree(_rootNode, *geometry);

    checkIfTexturesFinished();
}
void ObjModel::ReadFile(string fileName)
{
	Reset();

	int t1 = fileName.find_last_of('/');
	if (t1 == string::npos)
	{
		path = "";
	}
	else
	{
		path = fileName.substr(0, t1 + 1);
	}

	string temp;
	char c, buf[256];

	ifstream objFile(fileName);

	if (!objFile.is_open())
	{
		cout << fileName << " couldn't be opened.\n";
		system("pause");
		exit(1);
	}

	c = objFile.peek();

	while (c == '#' || c == '\n' || c == ' ')
	{
		objFile.getline(buf, 255);
		c = objFile.peek();
	}

	c = objFile.peek();
	if (c == 'm')
	{
		objFile >> temp;
		objFile >> temp;
	}
Esempio n. 9
0
int main(int argc, char** argv)
{
#define MAX_OBJ_FILENAME 500;
	std::string  modelName;
	if (argc != 2) {
		std::cerr << "Usage: " << argv[0] << " <model.obj>" << std::endl;
#if _DEBUG
		modelName = std::string("test.obj");
#else
		return -1;
#endif

	} else {
		modelName = std::string(argv[1]);
	}

	std::cout << "Loading " << modelName << std::endl;
	std::string modelPath(MODEL_DIRECTORY);
	modelPath += std::string(DIRECTORY_SEPARATOR) + modelName;
	std:: ifstream objFile(modelPath.c_str());

#if _MSC_VER
	std::cerr << "MSVC detected" << std::endl;
#else
	if (false == objFile.is_open())
	{
		std::cerr << "Unable to load " << modelPath << std::endl;
		return -2;
	}
#endif

	MyGLApp objViewer(modelName.c_str());
	objViewer.start();
	SDL_Quit();
	return 0;
}
Esempio n. 10
0
Material ModelLoader::loadMaterialFromMTL( string p_materialFileName )
{
	Material material;
	MaterialStruct mtrStruct;
	fstream objFile(p_materialFileName);

	if(objFile)
	{
		string line;
		string prefix;

		while(objFile.eof() == false)
		{
			prefix = "NULL"; //leave nothing from the previous iteration
			stringstream lineStream;

			getline(objFile, line);
			lineStream << line;
			lineStream >> prefix;

			if(prefix == "map_Kd")
			{
				string materialTextureName;
				lineStream >> materialTextureName;
				wstring name (materialTextureName.begin(), materialTextureName.end());
				D3DTexture* texture = new D3DTexture(m_pDevice, m_pDeviceContext);
				texture->createTexture(&name, NULL, false);
				material.setTexture(texture);
				//m_material->m_textureResource = createTexture(materialTextureName);
			}
			else if(prefix == "Ns")
			{
				int nShininess;
				lineStream >> nShininess;
				mtrStruct.m_ambient.w = nShininess;
			}
int Model_OBJ::Load(std::string filename)
{
    string line;
    ifstream objFile (filename + ".obj");	
    if (objFile.is_open())													// If obj file is open, continue
    {
        objFile.seekg (0, ios::end);										// Go to end of the file, 
        long fileSize = objFile.tellg();									// get file size
        objFile.seekg (0, ios::beg);										// we'll use this to register memory for our 3d model
 
        vertexBuffer = (float*) malloc (fileSize);							// Allocate memory for the verteces
        Faces_Triangles = (float*) malloc(fileSize*sizeof(float));			// Allocate memory for the triangles
        normals  = (float*) malloc(fileSize*sizeof(float));					// Allocate memory for the normals
 
        int triangle_index = 0;												// Set triangle index to zero
        int normal_index = 0;												// Set normal index to zero
 
        while (! objFile.eof() )											// Start reading file data
        {		
            getline (objFile,line);											// Get line from file
 
            if (line.c_str()[0] == 'v')										// The first character is a v: on this line is a vertex stored.
            {
                line[0] = ' ';												// Set first character to 0. This will allow us to use sscanf
 
                sscanf(line.c_str(),"%f %f %f ",							// Read floats from the line: v X Y Z
                    &vertexBuffer[TotalConnectedPoints],
                    &vertexBuffer[TotalConnectedPoints+1], 
                    &vertexBuffer[TotalConnectedPoints+2]);
 
                TotalConnectedPoints += POINTS_PER_VERTEX;					// Add 3 to the total connected points
            }
            if (line.c_str()[0] == 'f')										// The first character is an 'f': on this line is a point stored
            {
                line[0] = ' ';												// Set first character to 0. This will allow us to use sscanf
 
                int vertexNumber[4] = { 0, 0, 0 };
                sscanf(line.c_str(),"%i%i%i",								// Read integers from the line:  f 1 2 3
                    &vertexNumber[0],										// First point of our triangle. This is an 
                    &vertexNumber[1],										// pointer to our vertexBuffer list
                    &vertexNumber[2] );										// each point represents an X,Y,Z.
 
                vertexNumber[0] -= 1;										// OBJ file starts counting from 1
                vertexNumber[1] -= 1;										// OBJ file starts counting from 1
                vertexNumber[2] -= 1;										// OBJ file starts counting from 1
 
 
                /********************************************************************
                 * Create triangles (f 1 2 3) from points: (v X Y Z) (v X Y Z) (v X Y Z). 
                 * The vertexBuffer contains all verteces
                 * The triangles will be created using the verteces we read previously
                 */
 
                int tCounter = 0;
                for (int i = 0; i < POINTS_PER_VERTEX; i++)					
                {
                    Faces_Triangles[triangle_index + tCounter   ] = vertexBuffer[3*vertexNumber[i] ];
                    Faces_Triangles[triangle_index + tCounter +1 ] = vertexBuffer[3*vertexNumber[i]+1 ];
                    Faces_Triangles[triangle_index + tCounter +2 ] = vertexBuffer[3*vertexNumber[i]+2 ];
                    tCounter += POINTS_PER_VERTEX;
                }
 
                /*********************************************************************
                 * Calculate all normals, used for lighting
                 */ 
                float coord1[3] = { Faces_Triangles[triangle_index], Faces_Triangles[triangle_index+1],Faces_Triangles[triangle_index+2]};
                float coord2[3] = {Faces_Triangles[triangle_index+3],Faces_Triangles[triangle_index+4],Faces_Triangles[triangle_index+5]};
                float coord3[3] = {Faces_Triangles[triangle_index+6],Faces_Triangles[triangle_index+7],Faces_Triangles[triangle_index+8]};
                float *norm = this->calculateNormal( coord1, coord2, coord3 );
 
                tCounter = 0;
                for (int i = 0; i < POINTS_PER_VERTEX; i++)
                {
                    normals[normal_index + tCounter ] = norm[0];
                    normals[normal_index + tCounter +1] = norm[1];
                    normals[normal_index + tCounter +2] = norm[2];
                    tCounter += POINTS_PER_VERTEX;
                }
 
                triangle_index += TOTAL_FLOATS_IN_TRIANGLE;
                normal_index += TOTAL_FLOATS_IN_TRIANGLE;
                TotalConnectedTriangles += TOTAL_FLOATS_IN_TRIANGLE;			
            }	
        }
        objFile.close();														// Close OBJ file
    }
    else 
    {
        cout << "Unable to open file";								
    }
    //loads color;
    ifstream colFile (filename + ".txt");	
    if (colFile.is_open()) {
        colFile >> color[0];
        colFile >> color[1];
        colFile >> color[2];
        colFile.close();
    }
Esempio n. 12
0
void SphereGenerator::output()
{
//    texture = cv::imread(sTexture.toStdString().c_str());
//    QDateTime currTime = QDateTime::currentDateTime();
//    long long timeStamp = currTime.toMSecsSinceEpoch();
    std::ofstream out(sObj.toStdString().c_str());
    // for usemtl
    QString keyWords = "wire_sphere";
    out << "# created by h005 SphereGenerator" << std::endl;
    out << std::endl;
    // mtl file
    QFileInfo objFile(sObj);
    QString mtlFile(objFile.absolutePath());
    mtlFile.append("/");
    mtlFile.append(objFile.baseName());
    mtlFile.append(".mtl");
    QFileInfo mtlFileInfo(mtlFile);

    out << "mtllib "<< mtlFileInfo.fileName().toStdString() <<std::endl;

    for(int i=0;i<centerList.size();i++)
        out << "v "<< centerList.at(i).x
                  << " " << centerList.at(i).y
                  << " " << centerList.at(i).z << std::endl;

    out << "# "<< centerList.size() << " vertices" << std::endl;

    if(isCircle)
        sZ++;

    float uStep = 1.0 / (float)(sX-1);
    float vStep = 1.0 / (float)(sZ-1);

//    float u = 1.0f,v = 1.0f;
    float u = 0.f, v = 1.0f;
    for(int i=0;i<sX;i++)
    {
        v = 1.0f;
        for(int j=0;j<sZ;j++)
        {
            out << "vt " << u << " " << v << std::endl;
            v -= vStep;
            if( v < 0.f)
                v = 0.f;
        }
        u += uStep;
        if(u > 1.f)
            u = 1.f;
    }

    out << "# "<< centerList.size() << " texture coords" << std::endl;

    out << "g " << "Sphere 001"<< std::endl;

//    out << "usemtl " << keyWords.toStdString() << std::endl;

    out << "s 1" << std::endl;

    if(!isCircle)
    {
        for(int i=0;i<sX-1;i++)
        {
            for(int j=1;j<sZ;j++)
            {
                out << "f " << i * sZ + j << "/" << i * sZ + j << " ";
                out << (i+1) * sZ + j << "/" << (i+1) * sZ + j << " ";
                out << (i+1) * sZ + j + 1 << "/" << (i+1) * sZ + j + 1 << " ";
                out << i * sZ + j + 1 << "/" << i * sZ + j + 1 << std::endl;
            }
        }
        out << "# "<<(sX-1)*(sZ-1)<<" polygons"<<std::endl;
    }
    else
    {
        // 先完成环的那部分
        sZ--;
        for(int i=0;i<sX-1;i++)
        {
            for(int j=1;j<sZ;j++)
            {
                out << "f " << i * sZ + j << "/" << i * (sZ + 1) + j << " ";
                out << (i+1) * sZ + j << "/" << (i+1) * (sZ + 1) + j << " ";
                out << (i+1) * sZ + j + 1 << "/" << (i+1) * (sZ + 1) + j + 1 << " ";
                out << i * sZ + j + 1 << "/" << i * (sZ + 1) + j + 1 << std::endl;
            }
        }

        // 将环给衔接起来
            for(int i=0;i<sX-1;i++)
            {
                out << "f " << i * sZ + 1 << "/" << (i + 1) * (sZ + 1) << " ";
                out << (i+1) * sZ << "/" << (i+1) * (sZ + 1) - 1 << " ";
                out << (i+2) * sZ << "/" << (i+2) * (sZ + 1) - 1 << " ";
                out << (i+1) * sZ + 1 << "/" << (i+2) * (sZ + 1) << std::endl;
            }

        out << "# "<<(sX)*(sZ-1)<<" polygons"<<std::endl;
    }

    out.close();

    std::cout << "mtlFile "<<mtlFile.toStdString() << std::endl;
    out.open(mtlFile.toStdString().c_str());

    out << "# created by h005 SphereGenerator" << std::endl;
    out << "newmtl wire_plane" << std::endl;
    out << "	Ns 32"<< std::endl;
    out << "	d 1"<< std::endl;
    out << "	Tr 0" << std::endl;
    out << "	Tf 1 1 1"<< std::endl;
    out << "	illum 2" << std::endl;
    out << "	Ka 0.7765 0.8824 0.3412"<< std::endl;
    out << "	Kd 0.7765 0.8824 0.3412"<< std::endl;
    out << "	Ks 0.3500 0.3500 0.3500"<< std::endl;
    QFileInfo textureInfo(sTexture);
    out << "	map_Ka "<< textureInfo.fileName().toStdString() << std::endl;
    out << "	map_Kd "<< textureInfo.fileName().toStdString() << std::endl;

    out.close();
}
Esempio n. 13
0
DWORD PE::AddSection(LPBYTE pBuffer,DWORD dwSize,PCHAR pszSectionName)
{
	//修改文件头中的区段数量
	m_pNt->FileHeader.NumberOfSections++;
	//增加区段表项
	memset(m_pLastSection,0,sizeof(IMAGE_SECTION_HEADER));
	//写入区段名
	strcpy_s((char*)m_pLastSection->Name,IMAGE_SIZEOF_SHORT_NAME,pszSectionName);
	//区段虚拟大小
	DWORD dwVirtualSize=0;
	//区段文件大小
	DWORD dwSizeOfRawData=0;
	//把文件加载到内存所需要的大小  
	DWORD dwSizeOfImage=m_pNt->OptionalHeader.SizeOfImage;
	//取余 查看内存是否对齐 
	if (dwSizeOfImage%m_dwMemAlign)
	{
		// 取商再原来基础上+1  比如说dwSizeOfImage=1726 对齐粒度m_dwMemAlign=200 
		//此时dwSizeOfImage=1800
		dwSizeOfImage=(dwSizeOfImage/m_dwMemAlign+1)*m_dwMemAlign;
	}
	else
	{
		dwSizeOfImage=(dwSizeOfImage/m_dwMemAlign)*m_dwMemAlign;
	}

	//区段对齐后的RVA(dwSize) /内存对齐粒度 m_dwMemAlign
	if (dwSize%m_dwMemAlign)
	{
		dwVirtualSize=(dwSize/m_dwMemAlign+1)*m_dwMemAlign;
	}
	else
	{
		dwVirtualSize=(dwSize/m_dwMemAlign)*m_dwMemAlign;
	}

	//区段对齐后的RVA(dwSize) /文件对齐粒度 m_dwMemAlign
	if (dwSize%m_dwFileAlign)
	{
		dwSizeOfRawData=(dwSize/m_dwFileAlign+1)*m_dwFileAlign;
	}
	else
	{
		dwSizeOfRawData=(dwSize/m_dwFileAlign)*m_dwFileAlign;
	}

	//获取到新的相对虚拟地址 RVA
	m_pLastSection->VirtualAddress=(m_pLastSection[-1].VirtualAddress+(dwSize/m_dwMemAlign)*m_dwMemAlign);
	//区段在文件中的偏移
	m_pLastSection->PointerToRawData=m_dwFileSize;
	//区段在文件中大小
	m_pLastSection->SizeOfRawData=dwSizeOfRawData;
	//区段在内存中大小
	m_pLastSection->Misc.VirtualSize=dwVirtualSize;
	//区段属性
	m_pLastSection->Characteristics=0Xe0000040;

	//增加 文件大小 创建文件 添加代码段 确定入口点
	m_pNt->OptionalHeader.SizeOfImage=dwSizeOfImage+dwVirtualSize;
	m_pNt->OptionalHeader.AddressOfEntryPoint=m_dwNewOEP+m_pLastSection->VirtualAddress;

	//生成输出文件路径
	CString strPath=m_objFIle.GetFilePath();
	TCHAR SzOutPath[MAX_PATH]={0};
	//获取文件后缀名
	LPWSTR strSuffix=PathFindExtension(strPath);
	//目标文件路径到SzOutPath
	wcsncpy_s(SzOutPath,MAX_PATH,strPath,wcslen(strPath));

	//移除后缀名
	PathRemoveExtension(SzOutPath);
	// 在路径最后附加“_1”
	wcscat_s(SzOutPath,MAX_PATH,L"_1");
	// 在路径最后附加刚刚保存的后缀名
	wcscat_s(SzOutPath, MAX_PATH, strSuffix);                           

	//创建文件
	CFile objFile(SzOutPath,CFile::modeCreate|CFile::modeReadWrite);
	objFile.Write(m_pFileBase,(DWORD)m_objFIle.GetLength());
	//移到文件尾
	objFile.SeekToEnd();
	//将pBuffer 按照大小dwSize 写入文件
	objFile.Write(pBuffer,dwSize);
	//返回操作完成后的最后一个区段的相对虚拟地址 RAV
	return m_pLastSection->VirtualAddress;

}
Esempio n. 14
0
void ObjGPUData::loadObject(const char* fileName)
{
    std::string folderName = fileName;

    for(int i = folderName.size() - 1; i >= 0; i--)
    {
        if(folderName[i] == '/' || folderName[i] == '\\')
        {
            folderName = folderName.substr(0, i+1);
            break;
        }
        if(i == 0)
            folderName = "";
    }

    std::string objFileName = fileName;
    std::string mtlFileName = fileName;
    objFileName += ".obj";
    mtlFileName += ".mtl";

    std::ifstream mtlFile(mtlFileName.c_str(), std::ios::in);

    if(!mtlFile.is_open())
    {
        printf("Failed to open object %s\n", objFileName.c_str());
        exit(1);
    }

    std::string dataTypeString;
    float xVal, yVal, zVal;
    std::string valString;
    std::stringstream valStream;
    int iVal;

    while(mtlFile >> dataTypeString)
    {

        mtlDataType mtlDataTypeVal = getMtlDataType(dataTypeString);

        switch(mtlDataTypeVal)
        {
        case mtlDataType::mtlDataNEWMTL:
            mtlFile >> valString;
            materials.push_back(Material(valString));
            valString.clear();
            break;

        case mtlDataType::mtlDataNS:
            mtlFile >> xVal;
            materials.back().shine = xVal;
            break;

        case mtlDataType::mtlDataKA:
            mtlFile >> xVal;
            mtlFile >> yVal;
            mtlFile >> zVal;

            materials.back().Ka = glm::vec3(xVal, yVal, zVal);

            break;

        case mtlDataType::mtlDataKD:
            mtlFile >> xVal;
            mtlFile >> yVal;
            mtlFile >> zVal;

            materials.back().Kd = glm::vec3(xVal, yVal, zVal);

            break;

        case mtlDataType::mtlDataKS:
            mtlFile >> xVal;
            mtlFile >> yVal;
            mtlFile >> zVal;

            materials.back().Ks = glm::vec3(xVal, yVal, zVal);

            break;

        case mtlDataType::mtlDataMAP:
        {
            if(materials.back().textureSet)
                break;
            getline(mtlFile, valString);
            int fileNameLocation = valString.find_last_of("/\\");
            if(fileNameLocation != -1)
                valString = valString.substr(fileNameLocation + 1);
            while(valString[0] == ' ' || valString[0] == '\t')
                valString = valString.substr(1);
            if(valString.size() < 4 || valString.substr(valString.size() - 4) != ".dds")
            {
                valString = valString.substr(0, valString.find_last_of('.') + 1);
                valString += "dds";
            }
            materials.back().textureName = valString;
            bool textureExists = false;
            for(int i = 0; i < materials.size() - 1; i++)
            {
                if(materials[i].textureName == valString)
                {
                    textureExists = true;
                    materials.back().texture = materials[i].texture;
                    break;
                }
            }
            if(textureExists)
            {
                valString.clear();
                break;
            }
            materials.back().texture = loadImage((folderName + valString).c_str());
            materials.back().textureSet = true;
            valString.clear();
            break;
        }

        case mtlDataType::mtlDataBUMP:
        {
            if(materials.back().bumpSet)
                break;
            getline(mtlFile, valString);
            int fileNameLocation = valString.find_last_of("/\\");
            if(fileNameLocation != -1)
                valString = valString.substr(fileNameLocation + 1);
            while(valString[0] == ' ' || valString[0] == '\t')
                valString = valString.substr(1);
            if(valString.size() < 4 || valString.substr(valString.size() - 4) != ".dds")
            {
                valString = valString.substr(0, valString.find_last_of('.') + 1);
                valString += "dds";
            }
            materials.back().bumpName = valString;
            bool bumpExists = false;
            for(int i = 0; i < materials.size() - 1; i++)
            {
                if(materials[i].bumpName == valString)
                {
                    bumpExists = true;
                    materials.back().bump = materials[i].bump;
                    break;
                }
            }
            if(bumpExists)
            {
                valString.clear();
                break;
            }
            materials.back().bump = loadImage((folderName + valString).c_str());
            materials.back().bumpSet = true;
            valString.clear();
            break;
        }

        default:
            break;
        }
    }

    mtlFile.close();

    printf("Loading object %s... ", objFileName.c_str());

    std::ifstream objFile(objFileName.c_str(), std::ios::in);

    if(!objFile.is_open())
    {
        printf("Failed to open object %s\n", objFileName.c_str());
        exit(1);
    }

    std::vector<glm::vec3> vList_in;
    std::vector<glm::vec2> vTextureList_in;
    std::vector<glm::vec3> vNormalList_in;
    std::vector<GLuint> iVertex;
    std::vector<GLuint> iTexture;
    std::vector<GLuint> iNormal;

    std::vector<unsigned int> materialIndices_in;

    while(objFile >> dataTypeString)
    {

        dataType dataTypeVal = getDataType(dataTypeString);

        switch(dataTypeVal)
        {
        case dataType::dataV:
            objFile >> xVal;
            objFile >> yVal;
            objFile >> zVal;

            vList_in.push_back(glm::vec3(xVal, yVal, zVal));

            break;

        case dataType::dataVT:
            objFile >> xVal;
            objFile >> yVal;

            vTextureList_in.push_back(glm::vec2(xVal, yVal));

            break;

        case dataType::dataVN:
            objFile >> xVal;
            objFile >> yVal;
            objFile >> zVal;

            vNormalList_in.push_back(glm::vec3(xVal, yVal, zVal));

            break;

        case dataType::dataUSEMTL:
        {
            int index = -1;
            objFile >> valString;

            for(int i = 0; i < materials.size(); i++)
            {
                if(materials[i].materialName == valString)
                {
                    index = i;
                    break;
                }
            }

            if(index == -1)
                exit(1);

            valString.clear();

            materialIndices_in.push_back(iVertex.size());
            materialIndices_in.push_back(index);

            break;
        }


        case dataType::dataF:
        {
            char lastChar;

            for(int i = 0; i < 3; i++)
            {
                getline(objFile, valString, '/');
                valStream << valString;
                valString.clear();
                valStream >> iVal;
                valStream.str(std::string());
                valStream.clear();
                iVertex.push_back(iVal);

                getline(objFile, valString, '/');
                valStream << valString;
                valString.clear();
                valStream >> iVal;
                valStream.str(std::string());
                valStream.clear();
                iTexture.push_back(iVal);

                objFile >> iVal;
                iNormal.push_back(iVal);

                lastChar = objFile.get();
            }

            if(lastChar != '\n')
            {
                while(objFile.peek() == ' ' || objFile.peek() == '\t')
                {
                    objFile.get();
                }

                if(objFile.peek() == '\n')
                    break;

                iVertex.push_back(iVertex[iVertex.size() - 3]);
                iTexture.push_back(iTexture[iTexture.size() - 3]);
                iNormal.push_back(iNormal[iNormal.size() - 3]);

                iVertex.push_back(iVertex[iVertex.size() - 2]);
                iTexture.push_back(iTexture[iTexture.size() - 2]);
                iNormal.push_back(iNormal[iNormal.size() - 2]);

                getline(objFile, valString, '/');
                valStream << valString;
                valString.clear();
                valStream >> iVal;
                valStream.str(std::string());
                valStream.clear();
                iVertex.push_back(iVal);

                getline(objFile, valString, '/');
                valStream << valString;
                valString.clear();
                valStream >> iVal;
                valStream.str(std::string());
                valStream.clear();
                iTexture.push_back(iVal);

                objFile >> iVal;
                iNormal.push_back(iVal);
            }

            break;
        }

        default:
            break;
        }
    }

    objFile.close();

    int first, last;

    std::map<FullVertex,unsigned int> vertexToOutIndex;

    for(int k = 0; k < materialIndices_in.size()/2; ++k)
    {

        first = materialIndices_in[2*k];
        if((2*k + 2) > (materialIndices_in.size() - 1))
            last = iVertex.size();
        else
            last = materialIndices_in[2*k + 2];

        materialIndices.push_back(fList.size());
        materialIndices.push_back(materialIndices_in[2*k + 1]);

        for(int i = first; i < last; i++)
        {

            FullVertex nextVertex = {vList_in[iVertex[i] - 1], vTextureList_in[iTexture[i] - 1], vNormalList_in[iNormal[i] - 1]};

            std::map<FullVertex,unsigned int>::iterator vLocation = vertexToOutIndex.find(nextVertex);

            if(vLocation == vertexToOutIndex.end())
            {
                vList.push_back(vList_in[iVertex[i]-1]);
                vTextureList.push_back(vTextureList_in[iTexture[i]-1]);
                vNormalList.push_back(vNormalList_in[iNormal[i]-1]);

                vertexToOutIndex[nextVertex] = vList.size() - 1;
                fList.push_back(vList.size() - 1);
            }
            else
            {
                fList.push_back(vLocation->second);
            }
        }
    }


    //  Invert all texture v-coordinates for use with DXT compression textures

    for(int i = 0; i < vTextureList.size(); i++)
    {
        vTextureList[i][1] = 1 - vTextureList[i][1];
    }


    //  Generate tangent vectors for normals
    //  Sourced from http://www.terathon.com/code/tangent.html

    std::vector<glm::vec3> tan1(vList.size());
    std::vector<glm::vec3> tan2(vList.size());

    for (unsigned int a = 0; a < fList.size(); a+=3)
    {
        GLuint i1 = fList[a + 0];
        GLuint i2 = fList[a + 1];
        GLuint i3 = fList[a + 2];

        glm::vec3 v1 = vList[i1];
        glm::vec3 v2 = vList[i2];
        glm::vec3 v3 = vList[i3];

        glm::vec2 w1 = vTextureList[i1];
        glm::vec2 w2 = vTextureList[i2];
        glm::vec2 w3 = vTextureList[i3];

        float x1 = v2.x - v1.x;
        float x2 = v3.x - v1.x;
        float y1 = v2.y - v1.y;
        float y2 = v3.y - v1.y;
        float z1 = v2.z - v1.z;
        float z2 = v3.z - v1.z;

        float s1 = w2.x - w1.x;
        float s2 = w3.x - w1.x;
        float t1 = w2.y - w1.y;
        float t2 = w3.y - w1.y;

        float r = 1.0f / (s1 * t2 - s2 * t1);

        glm::vec3 sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
        glm::vec3 tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

        tan1[i1] += sdir;
        tan1[i2] += sdir;
        tan1[i3] += sdir;

        tan2[i1] += tdir;
        tan2[i2] += tdir;
        tan2[i3] += tdir;
    }

    for (unsigned int a = 0; a < vList.size(); a++)
    {
        glm::vec3 n = vNormalList[a];
        glm::vec3 t = tan1[a];

        // Gram-Schmidt orthogonalize
        glm::vec4 tangent = glm::vec4(glm::normalize(t - n * glm::dot(n, t)), 0.0f);

        // Calculate handedness
        tangent.w = (glm::dot(glm::cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;

        vTangentList.push_back(tangent);
    }

    printf("DONE\n");

    return;

}
Esempio n. 15
0
File: run.cpp Progetto: bihai/fbide
/**
 * MyFrame::Compile
 * This function compiles given src file. It calls MyFrame::GetCompileData to
 * receave data.
 * @param index about file from buffer list
 * @return int 0 on success, 1 on failure
 */
int MyFrame::Compile ( int index ) {

    //Safety checks
    if ( !stc )
        return 1;
    if ( ProcessIsRunning )
        return 1;
    
    // these are used to get the first error
    bool isFirstErrorFound = false;
    wxString strFirstErrorFile;
    int intFirstErrorLine;
        
    // File that we are about to compile
    wxFileName objFile( bufferList[ index ]->GetFileName() );
    objFile.Normalize();

    // Get compiler cmdline and check it. if empty return.
    wxString strCompile( GetCompileData( index ) );
    if( !strCompile.Len() )
        return 1;

    // Log compiler output and input
    strCompilerOutput.Empty();
    strCompilerOutput.Add("[bold]Command executed:[/bold]");
    strCompilerOutput.Add(strCompile);

    // If Active path is activated then set current working path
    // to show to the location of the src file.
    if( Prefs.ActivePath )
        ::wxSetWorkingDirectory( objFile.GetPath() );

    // Execute fbc and retreave results.
    wxArrayString arrOutput, arrErrOutput;
    int intCompileResult = wxExecute( strCompile, arrOutput, arrErrOutput );

    // if there was any output from fbc then get output messages and put them
    // into console area
    if ( arrOutput.Count() || arrErrOutput.Count() ) {
        // define variables
        wxString        strOutput;
        wxString        strTemp;
        wxFileName      objOutputFile;
        long            intOutput;
        long            intLine;
        int             intBraceStart;
        int             intBraceEnd;
        bool            isOutputHeader = false;
        
        wxString        strDebug;

        // Becouse fbc returns Outputs via both std and error channels,
        // we need to join them here.
        WX_APPEND_ARRAY( arrOutput, arrErrOutput );

        // Putput logging:
        strCompilerOutput.Add( "" );
        strCompilerOutput.Add( "[bold]Compiler output:[/bold]" );

        // Loop through arrOutput
        for ( unsigned int cnt = 0; cnt < arrOutput.Count(); cnt++ ) {
            if ( arrOutput[cnt].IsEmpty() )
                continue;

            // Log compiler output
            strCompilerOutput.Add( arrOutput[cnt] );

            intBraceStart = arrOutput[cnt].First( '(' );
            intBraceEnd = arrOutput[cnt].First( ')' );

            // if intBraceStart is not -1 then probably line number was found.
            // as fbc returns things: file(linenumber): Error|Warning nr: Output message
            // As it might be any message then test if first part is a filename.
            // colon[:] - win32
            // slash[/] -linux
#ifdef __WXMSW__

            if( intBraceStart != -1 && intBraceEnd != -1 && arrOutput[cnt].GetChar(1) == ':' ) {
#else
            if( intBraceStart != -1 && intBraceEnd != -1 && arrOutput[cnt].GetChar(0) == '/' ) {
#endif
                // Get possible line and error number.
                strTemp = arrOutput[cnt].Mid( intBraceStart + 1, intBraceEnd - intBraceStart - 1);

                // if this is a number:
                if ( strTemp.IsNumber() ) {
                    strTemp.ToLong( &intLine );
                    // Get possible file name and check if it is indeed a filename
                    objOutputFile = arrOutput[cnt].Left( intBraceStart );
                    objOutputFile.Normalize();
                    if ( objOutputFile.IsOk() && objOutputFile.FileExists() ) {
                        //Now that it's indeed is a filename, get line, error/warning number
                        //and Output message on that line
                        strTemp = arrOutput[cnt].Mid( intBraceEnd + 4 );
                        strTemp = strTemp.Mid( strTemp.Find( ' ' ) + 1 );
                        strOutput = strTemp.Mid( strTemp.Find( ':' ) + 2 );
                        strTemp = strTemp.Left( strTemp.Find( ':' ) );
                        strTemp.ToLong( &intOutput );
                        isOutputHeader = true;
                    }
                }
            }

            // If is Output header ( includes filename, Output number and line number then
            // add generated values. Else just add original message.
            if( isOutputHeader ) {
                isOutputHeader = false;
                if ( intOutput == 0 )
                    intOutput = -1;
                if ( !isFirstErrorFound ) {
                    strFirstErrorFile = objOutputFile.GetFullPath();
                    intFirstErrorLine = intLine;
                    isFirstErrorFound = true;
                }
                AddListItem(intLine, intOutput, objOutputFile.GetFullPath(), strOutput);
            }
            else {
                // Replace all tabs.
                arrOutput[cnt].Replace( "\t", "  " );
                AddListItem(-1, -1, "", arrOutput[cnt]);
            }
        }

        // Open console area
        if ( !HSplitter->IsSplit() ) {
            HSplitter->SplitHorizontally( FBCodePanel, FBConsole, ConsoleSize );
            FB_View->Check(Menu_Result, true);
        }

    }
    else {
        // Since there was no output then close console area
        // -if no error then it is not needed.
        if ( HSplitter->IsSplit() ) {
Esempio n. 16
0
sptr(Resource) DecoderOBJ::decode(const std::string &path)
{
    clear();

    TextFile objFile(path);

    std::string line;
    do
    {
        line = objFile.getLine();

        if (line == "END_OF_FILE")
            break;

        if (line.find("vt") != std::string::npos)
        { }

        if (line.find("vn") != std::string::npos)
            appendNormal(line);

        if (line.find("vp") != std::string::npos)
        { }

        if (line.at(0) == 'v')
            appendVertex(line);

        if (line.at(0) == 'f')
            appendFace(line);

        line.clear();

    } while (line.empty());

    if (faces.empty() || vertexList.empty())
    {
        syslog << "Unable to parse .obj file" << path << logwarn;
        return sptr(Resource)();
    }

    auto newMesh = std::make_shared<rend::Mesh>();

    triangulateModel();

    rend::VertexBuffer vb;
    vb.setType(rend::VertexBuffer::INDEXEDTRIANGLELIST);
    vb.appendVertices(vertexList, resultTrianglesIndices, !normalsList.empty());

    auto material = std::make_shared<rend::Material>();

    material->plainColor = rend::Color3(255, 255, 255);
    material->ambientColor = rend::Color3(255, 255, 255);
    material->diffuseColor = rend::Color3(255, 255, 255);

    material->shadeMode = rend::Material::SM_FLAT;
    material->sideType = rend::Material::ONE_SIDE;

    vb.setMaterial(material);

    newMesh->appendSubmesh(vb);

    auto newObject = std::make_shared<rend::SceneObject>(newMesh);

    std::tr2::sys::path p(path);
    newObject->setName(p.filename());

    syslog << "Decoded obj-model \"" << newObject->getName()
           << "\". Number of vertices:" << newMesh->numVertices()
           << ". Number of faces:" << faces.size() << logmess;

    return newObject;
}
Esempio n. 17
0
int main(int argc, char** argv)
{
	float scale = 0.1f;
	float scaleTexV = -1.f;

	std::vector<Object> objects;
	std::ifstream inputFile(argv[1]);
	if (!inputFile.is_open())
	{
		printf("Failed to open %s", argv[1]);
		return -1;
	}

	if (argc != 3)
	{
		printf("Missing scene name");
		return -1;
	}
	std::string sceneName = argv[2];

	char line[1024];
	std::vector<Vec3> positions;
	std::vector<Vec3> normals;
	std::vector<Vec2> texcoords;

	Object* pActiveObj = nullptr;
	SubObject* pActiveSubObject = nullptr;

	int lineNum = 0;
	while (inputFile.getline(line, 1024))
	{
		++lineNum;

		char* context = nullptr;
		char* tok = strtok_s(line, " ", &context);
		if (!tok)
			continue;

		if (strcmp(tok, "v") == 0)
		{
			// Position
			Vec3 pos;
			pos.x = scale * (float)atof(strtok_s(nullptr, " ", &context));
			pos.y = scale * (float)atof(strtok_s(nullptr, " ", &context));
			pos.z = scale * (float)atof(strtok_s(nullptr, " ", &context));
			positions.push_back(pos);
		}
		else if (strcmp(tok, "vn") == 0)
		{
			// Normal
			Vec3 norm;
			norm.x = (float)atof(strtok_s(nullptr, " ", &context));
			norm.y = (float)atof(strtok_s(nullptr, " ", &context));
			norm.z = (float)atof(strtok_s(nullptr, " ", &context));
			normals.push_back(norm);
		}
		else if (strcmp(tok, "vt") == 0)
		{
			// Tex coord
			Vec2 uv;
			uv.x = (float)atof(strtok_s(nullptr, " ", &context));
			uv.y = (float)atof(strtok_s(nullptr, " ", &context)) * scaleTexV;
			texcoords.push_back(uv);
		}
		else if (strcmp(tok, "f") == 0)
		{
			// Face
			Vertex faceVerts[4];
			int numVerts = 0;

			while (context[0] != 0)
			{
				Vertex& rVert = faceVerts[numVerts];
				rVert.pos = atoi(strtok_s(nullptr, "/ ", &context)) - 1;
				rVert.uv = atoi(strtok_s(nullptr, "/ ", &context)) - 1;
				rVert.norm = atoi(strtok_s(nullptr, "/ ", &context)) - 1;

				++numVerts;
			}

			if (numVerts == 3)
			{
				pActiveSubObject->verts.push_back(faceVerts[0]);
				pActiveSubObject->verts.push_back(faceVerts[1]);
				pActiveSubObject->verts.push_back(faceVerts[2]);
			}
			else if (numVerts == 4)
			{
				pActiveSubObject->verts.push_back(faceVerts[0]);
				pActiveSubObject->verts.push_back(faceVerts[1]);
				pActiveSubObject->verts.push_back(faceVerts[2]);
				pActiveSubObject->verts.push_back(faceVerts[0]);
				pActiveSubObject->verts.push_back(faceVerts[2]);
				pActiveSubObject->verts.push_back(faceVerts[3]);
			}
			else
			{
				assert(false);
			}
		}
		else if (strcmp(tok, "g") == 0)
		{
			objects.emplace_back();
			pActiveObj = &objects.back();

			pActiveObj->name = strtok_s(nullptr, " ", &context);
		}
		else if (strcmp(tok, "usemtl") == 0)
		{
			pActiveObj->subobjects.emplace_back();
			pActiveSubObject = &pActiveObj->subobjects.back();

			pActiveSubObject->material = strtok_s(nullptr, " ", &context);
		}
	}

	Json::StyledStreamWriter jsonWriter;

	Json::Value jSceneRoot(Json::objectValue);

	// Camera
	{
		Json::Value jCamera(Json::objectValue);

		Json::Value jPos(Json::arrayValue);
		jPos[0] = 0.f;
		jPos[1] = 5.f;
		jPos[2] = 0.f;
		jCamera["position"] = jPos;

		Json::Value jRot(Json::arrayValue);
		jRot[0] = 0.f;
		jRot[1] = 0.f;
		jRot[2] = 0.f;
		jCamera["rotation"] = jRot;

		jSceneRoot["camera"] = jCamera;
	}

	jSceneRoot["sky"] = "cloudy";
	jSceneRoot["lights"] = Json::Value(Json::arrayValue);
	Json::Value& jSceneObjects = jSceneRoot["objects"] = Json::Value(Json::arrayValue);

	int numObjects = (int)objects.size();
	for (int i = 0; i < numObjects; ++i)
	{
		const Object& obj = objects[i];

		Vec3 minExtents = { FLT_MAX, FLT_MAX, FLT_MAX };
		Vec3 maxExtents = { -FLT_MAX, -FLT_MAX, -FLT_MAX };
		char str[256];

		for (unsigned int n = 0; n < obj.subobjects.size(); ++n)
		{
			const SubObject& subobj = obj.subobjects[n];
			for (unsigned int k = 0; k < subobj.verts.size(); ++k)
			{
				const Vertex& vert = subobj.verts[k];
				const Vec3& pos = positions[vert.pos];
				minExtents.x = min(minExtents.x, pos.x);
				minExtents.y = min(minExtents.y, pos.y);
				minExtents.z = min(minExtents.z, pos.z);
				maxExtents.x = max(maxExtents.x, pos.x);
				maxExtents.y = max(maxExtents.y, pos.y);
				maxExtents.z = max(maxExtents.z, pos.z);
			}
		}

		Vec3 center = { (maxExtents.x + minExtents.x) * 0.5f, minExtents.y, (maxExtents.z + minExtents.z) * 0.5f };

		std::string objFilename = "output/" + obj.name + ".obj";
		createDirectoryTreeForFile(objFilename);

		std::ofstream objFile(objFilename);
		assert(objFile.is_open());

		int posCount = 0;
		int uvCount = 0;
		int normCount = 0;

		for (unsigned int n = 0; n < obj.subobjects.size(); ++n)
		{
			const SubObject& subobj = obj.subobjects[n];

			// Build the obj file
			int posStart = INT_MAX;
			int posEnd = 0;
			int uvStart = INT_MAX;
			int uvEnd = 0;
			int normStart = INT_MAX;
			int normEnd = 0;

			for (unsigned int k = 0; k < subobj.verts.size(); ++k)
			{
				const Vertex& vert = subobj.verts[k];

				posStart = min(posStart, vert.pos);
				posEnd = max(posEnd, vert.pos);
				uvStart = min(uvStart, vert.uv);
				uvEnd = max(uvEnd, vert.uv);
				normStart = min(normStart, vert.norm);
				normEnd = max(normEnd, vert.norm);
			}

			// write positions
			for (int k = posStart; k <= posEnd; ++k)
			{
				const Vec3& pos = positions[k];
				sprintf_s(str, "v %f %f %f\n", (pos.x - center.x), (pos.y - center.y), (pos.z - center.z));
				objFile.write(str, strlen(str));
			}

			// write uvs
			for (int k = uvStart; k <= uvEnd; ++k)
			{
				const Vec2& uv = texcoords[k];
				sprintf_s(str, "vt %f %f\n", uv.x, uv.y);
				objFile.write(str, strlen(str));
			}

			// write normals
			for (int k = normStart; k <= normEnd; ++k)
			{
				const Vec3& normal = normals[k];
				sprintf_s(str, "vn %f %f %f\n", normal.x, normal.y, normal.z);
				objFile.write(str, strlen(str));
			}

			// write material to use for this subobject
			std::string materialName = sceneName + "/" + subobj.material;
			sprintf_s(str, "usemtl %s\n", materialName.c_str());
			objFile.write(str, strlen(str));

			// write faces
			for (unsigned int k = 0; k < subobj.verts.size(); k += 3)
			{
				const Vertex& vert1 = subobj.verts[k + 0];
				const Vertex& vert2 = subobj.verts[k + 1];
				const Vertex& vert3 = subobj.verts[k + 2];
				sprintf_s(str, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
					posCount + (vert1.pos - posStart + 1), uvCount + (vert1.uv - uvStart + 1), normCount + (vert1.norm - normStart + 1),
					posCount + (vert2.pos - posStart + 1), uvCount + (vert2.uv - uvStart + 1), normCount + (vert2.norm - normStart + 1),
					posCount + (vert3.pos - posStart + 1), uvCount + (vert3.uv - uvStart + 1), normCount + (vert3.norm - normStart + 1));
				objFile.write(str, strlen(str));
			}

			posCount += (posEnd - posStart) + 1;
			uvCount += (uvEnd - uvStart) + 1;
			normCount += (normEnd - normStart) + 1;
		}

		objFile.close();

		// Add instance to scene
		Json::Value& jObj = jSceneObjects.append(Json::objectValue);
		jObj["model"] = sceneName + "/" + obj.name;

		Json::Value& jPos = jObj["position"] = Json::arrayValue;
		jPos[0] = center.x; jPos[1] = center.y; jPos[2] = center.z;

		Json::Value& jRot = jObj["rotation"] = Json::arrayValue;
		jRot[0] = 0.f; jRot[1] = 0.f; jRot[2] = 0.f;

		Json::Value& jScale = jObj["scale"] = Json::arrayValue;
		jScale[0] = 1.f; jScale[1] = 1.f; jScale[2] = 1.f;
	}

	std::ofstream sceneFile("output/" + sceneName + ".scene");
	jsonWriter.write(sceneFile, jSceneRoot);
}
Esempio n. 18
0
void OBJExporter::Write( const char* relativePath, const char* basePath )
{
	idStrStatic< MAX_OSPATH > convertedFileName = relativePath;
	
	convertedFileName.SetFileExtension( ".obj" );
	idFileLocal objFile( fileSystem->OpenFileWrite( convertedFileName, basePath ) );
	
	convertedFileName.SetFileExtension( ".mtl" );
	idFileLocal mtlFile( fileSystem->OpenFileWrite( convertedFileName, basePath ) );
	
	int totalVerts = 0;
	
	for( int g = 0; g < groups.Num(); g++ )
	{
		const OBJGroup& group = groups[g];
		
		objFile->Printf( "g %s\n", group.name.c_str() );
		
		for( int o = 0; o < group.objects.Num(); o++ )
		{
			const OBJObject& geometry = group.objects[o];
			
			//objFile->Printf( "g %s\n", group.name.c_str() );
			//objFile->Printf( "o %s\n", geometry.name.c_str() );
			
			for( int i = 0; i < geometry.faces.Num(); i++ )
			{
				const OBJFace& face = geometry.faces[i];
				
				for( int j = 0; j < face.verts.Num(); j++ )
				{
					const idVec3& v = face.verts[j].xyz;
					
					objFile->Printf( "v %1.6f %1.6f %1.6f\n", v.x, v.y, v.z );
				}
				
				for( int j = 0; j < face.verts.Num(); j++ )
				{
					const idVec2& vST = face.verts[j].GetTexCoord();
					
					objFile->Printf( "vt %1.6f %1.6f\n", vST.x, vST.y );
				}
				
				for( int j = 0; j < face.verts.Num(); j++ )
				{
					const idVec3& n = face.verts[j].GetNormal();
					
					objFile->Printf( "vn %1.6f %1.6f %1.6f\n", n.x, n.y, n.z );
				}
				
				//objFile->Printf( "g %s\n", group.name.c_str() );
				//objFile->Printf( "o %s\n", geometry.name.c_str() );
				objFile->Printf( "usemtl %s\n", face.material->GetName() );
				
				objFile->Printf( "f " );
				//for( int j = 0; j < face.indexes.Num(); j++ )
				
				// flip order for OBJ
				for( int j = face.indexes.Num() - 1; j >= 0; j-- )
				{
					objFile->Printf( "%i/%i/%i ",
									 face.indexes[j] + 1 + totalVerts,
									 face.indexes[j] + 1 + totalVerts,
									 face.indexes[j] + 1 + totalVerts );
				}
				
				objFile->Printf( "\n\n" );
			}
			
			for( int i = 0; i < geometry.faces.Num(); i++ )
			{
				const OBJFace& face = geometry.faces[i];
				totalVerts += face.verts.Num();
			}
		}
	}
	
	for( int i = 0; i < materials.Num(); i++ )
	{
		const idMaterial* material = materials[i];
		
		mtlFile->Printf( "newmtl %s\n", material->GetName() );
		
		if( material->GetFastPathDiffuseImage() )
		{
			idStr path = material->GetFastPathDiffuseImage()->GetName();
			path.SlashesToBackSlashes();
			path.DefaultFileExtension( ".tga" );
			
			mtlFile->Printf( "\tmap_Kd //..\\..\\..\\%s\n", path.c_str() );
		}
		else if( material->GetEditorImage() )
		{
			idStr path = material->GetEditorImage()->GetName();
			path.SlashesToBackSlashes();
			path.DefaultFileExtension( ".tga" );
			
			mtlFile->Printf( "\tmap_Kd //..\\..\\..\\%s\n", path.c_str() );
		}
		
		
		mtlFile->Printf( "\n" );
	}
}
Esempio n. 19
0
bool MeshManager::importObjMesh(const char* filename)
{
	QElapsedTimer timer;
	timer.start();
	QFile objFile(filename);

	if (!objFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		std::cerr << "could not find file: " << filename;
		return false;
	}

	QTextStream stream(&objFile);

	std::shared_ptr<GenericDataArray<float> > vertices = std::make_shared<GenericDataArray<float> >();
	std::shared_ptr<GenericDataArray<unsigned int> > faces = std::make_shared<GenericDataArray<unsigned int> >();
	std::shared_ptr<GenericDataArray<float> > uniqueNormals = std::make_shared<GenericDataArray<float> >();
	std::vector<int> normalIndices;

	while (!stream.atEnd()) {
		QString linePrefix;
		stream >> linePrefix;

		QString line(stream.readLine());

		if (linePrefix != "#") {
			QStringList elements = line.split(' ', QString::SkipEmptyParts);

			//read vertices
			if (linePrefix == "v") {
				GenericDataArray<float>::value_type vertexPosition;
				vertexPosition[0] = elements.takeFirst().toFloat();
				vertexPosition[1] = elements.takeFirst().toFloat();
				vertexPosition[2] = elements.takeFirst().toFloat();

				vertices->push_back(vertexPosition);
			}

			//read normals
			if (linePrefix == "vn") {
				GenericDataArray<float>::value_type normal;
				normal[0] = elements.takeFirst().toFloat();
				normal[1] = elements.takeFirst().toFloat();
				normal[2] = elements.takeFirst().toFloat();

				uniqueNormals->push_back(normal);
			}

			//read faces
			else if (linePrefix == "f"){
				GenericDataArray<unsigned int>::value_type face;

				int i = 0;
				while (!elements.isEmpty() && i < 3) {
					QStringList faceElements = elements.takeFirst().split('/', QString::SkipEmptyParts);
					if (faceElements.size() == 2) {
						face[i] = faceElements.takeFirst().toInt() - 1;
						normalIndices.push_back(faceElements.takeFirst().toInt() - 1);
					}
					else {
						face[i] = faceElements.takeFirst().toInt() - 1;
					}

					++i;
				}

				faces->push_back(face);
			}
		}
	}

	std::shared_ptr<GenericDataArray<float> > normals; 

	//rearrange normals so that they can be accessed by the same index as vertices
	if (!uniqueNormals->empty()) {
		normals = std::make_shared<GenericDataArray<float> >(vertices->length());
		for (unsigned int i = 0; i < faces->length(); ++i) {
			for (unsigned int j = 0; j < 3; ++j) {
				int vertexIndex = faces->at(i, j);
				int normalIndex = normalIndices[i * 3 + j];
				normals->at(vertexIndex) = uniqueNormals->at(normalIndex);
			}
		}
	}
	else {
		normals = generateNormals(vertices, faces);
	}

	m_geomRoot = std::make_shared<sg::GroupNode>();
	m_geomRoot->addChild(createGeometryNode(vertices, normals, faces));

	std::cout << "Time: " << timer.elapsed() / 1000.0 << std::endl;
	std::cout << "Vertices: " << vertices->length() << std::endl;
	std::cout << "Faces: " << faces->length() << std::endl;

	return true;

}
Esempio n. 20
0
// CreateDynamicObjectNode
//------------------------------------------------------------------------------
bool ObjectListNode::CreateDynamicObjectNode( NodeGraph & nodeGraph, Node * inputFile, const AString & baseDir, bool isUnityNode, bool isIsolatedFromUnityNode )
{
    const AString & fileName = inputFile->GetName();

    // Transform src file to dst object path
    // get file name only (no path, no ext)
    const char * lastSlash = fileName.FindLast( NATIVE_SLASH );
    lastSlash = lastSlash ? ( lastSlash + 1 ) : fileName.Get();
    const char * lastDot = fileName.FindLast( '.' );
    lastDot = lastDot && ( lastDot > lastSlash ) ? lastDot : fileName.GetEnd();

    // if source comes from a directory listing, use path relative to dirlist base
    // to replicate the folder hierearchy in the output
    AStackString<> subPath;
    if ( baseDir.IsEmpty() == false )
    {
        ASSERT( NodeGraph::IsCleanPath( baseDir ) );
        if ( PathUtils::PathBeginsWith( fileName, baseDir ) )
        {
            // ... use everything after that
            subPath.Assign( fileName.Get() + baseDir.GetLength(), lastSlash ); // includes last slash
        }
    }
    else
    {
        if ( !m_BaseDirectory.IsEmpty() && PathUtils::PathBeginsWith( fileName, m_BaseDirectory ) )
        {
            // ... use everything after that
            subPath.Assign( fileName.Get() + m_BaseDirectory.GetLength(), lastSlash ); // includes last slash
        }
    }

    AStackString<> fileNameOnly( lastSlash, lastDot );
    AStackString<> objFile( m_CompilerOutputPath );
    objFile += subPath;
    objFile += m_CompilerOutputPrefix;
    objFile += fileNameOnly;
    objFile += GetObjExtension();

    // Create an ObjectNode to compile the above file
    // and depend on that
    Node * on = nodeGraph.FindNode( objFile );
    if ( on == nullptr )
    {
        // determine flags - TODO:B Move DetermineFlags call out of build-time
        const bool usingPCH = ( m_PrecompiledHeader != nullptr );
        uint32_t flags = ObjectNode::DetermineFlags( m_Compiler, m_CompilerArgs, false, usingPCH );
        if ( isUnityNode )
        {
            flags |= ObjectNode::FLAG_UNITY;
        }
        if ( isIsolatedFromUnityNode )
        {
            flags |= ObjectNode::FLAG_ISOLATED_FROM_UNITY;
        }
        uint32_t preprocessorFlags = 0;
        if ( m_Preprocessor )
        {
            // determine flags - TODO:B Move DetermineFlags call out of build-time
            preprocessorFlags = ObjectNode::DetermineFlags( m_Preprocessor, m_PreprocessorArgs, false, usingPCH );
        }

        on = nodeGraph.CreateObjectNode( objFile, inputFile, m_Compiler, m_CompilerArgs, m_CompilerArgsDeoptimized, m_PrecompiledHeader, flags, m_CompilerForceUsing, m_DeoptimizeWritableFiles, m_DeoptimizeWritableFilesWithToken, m_AllowDistribution, m_AllowCaching, m_Preprocessor, m_PreprocessorArgs, preprocessorFlags );
    }
    else if ( on->GetType() != Node::OBJECT_NODE )
    {
        FLOG_ERROR( "Node '%s' is not an ObjectNode (type: %s)", on->GetName().Get(), on->GetTypeName() );
        return false;
    }
    else
    {
        ObjectNode * other = on->CastTo< ObjectNode >();
        if ( inputFile != other->GetSourceFile() )
        {
            FLOG_ERROR( "Conflicting objects found:\n"
                        " File A: %s\n"
                        " File B: %s\n"
                        " Both compile to: %s\n",
                        inputFile->GetName().Get(),
                        other->GetSourceFile()->GetName().Get(),
                        objFile.Get() );
            return false;
        }
    }
    m_DynamicDependencies.Append( Dependency( on ) );
    return true;
}
//parse file, send vertices and indices to node's mesh using setVertices and setIndices
objLoader::objLoader(string file, Node* node) {

	ifstream objFile(file);

	if (!objFile.is_open()) {
		cout << "Could not open obj file." << endl;
	}

	else {

		//only need to handle the lines starting with v/vn/f 
		while (!objFile.eof()) {

			std::string line;
			std::getline(objFile, line);

			if (line.size() > 0) {

				// vertices
				if (line[0] == 'v' && line[1] == ' ') {
					float vx, vy, vz;
					sscanf_s(line.c_str() + 2, "%f %f %f", &vx, &vy, &vz);
					vertices_obj.push_back(glm::vec3(vx, vy, vz));
				}

				// normals
				if (line[0] == 'v' && line[1] == 'n') {
					float nx, ny, nz;
					sscanf_s(line.c_str() + 3, "%f %f %f", &nx, &ny, &nz);
					normals_obj.push_back(glm::vec3(nx, ny, nz));
				}

				// triangular faces: v/vt, v/vt/vn, or v//vn
				if (line[0] == 'f') {

					//f v/vt v/vt v/vt
					if (count(line.begin(), line.end(), '/') == 3) {
						int v1, v2, v3;
						int t1, t2, t3;

						sscanf_s(line.c_str() + 2, "%i/%i %i/%i %i/%i",
							 &v1, &t1, &v2, &t2, &v3, &t3);

						indices_obj.push_back(v1-1);
						indices_obj.push_back(v2-1);
						indices_obj.push_back(v3-1);
					}

					else {

						std::size_t found = line.find("//");

						//f v/vt/vn v/vt/vn v/vt/vn
						if (found == std::string::npos) {
							int v1, v2, v3;
							int t1, t2, t3;
							int n1, n2, n3;

							sscanf_s(line.c_str() + 2, "%f/%f/%f %f/%f/%f %f/%f/%f",
								 &v1, &t1, &n1, &v2, &t2, &n2, &v3, &t3, &n3);

							indices_obj.push_back(v1-1);
							indices_obj.push_back(v2-1);
							indices_obj.push_back(v3-1);

							norm_indices_obj.push_back(n1-1);
							norm_indices_obj.push_back(n2-1);
							norm_indices_obj.push_back(n3-1);
						}

						//f v//vn v//vn v//vn
						else {
							int v1, v2, v3;
							int n1, n2, n3;

							sscanf_s(line.c_str() + 2, "%f//%f %f//%f %f//%f",
								 &v1, &n1, &v2, &n2, &v3, &n3);

							indices_obj.push_back(v1-1);
							indices_obj.push_back(v2-1);
							indices_obj.push_back(v3-1);

							norm_indices_obj.push_back(n1-1);
							norm_indices_obj.push_back(n2-1);
							norm_indices_obj.push_back(n3-1);
						}
					}
				}
			}
		}
	}

	if (node->getGeometry()->getGeometryType() == 3) {
		Mesh* shape = new Mesh();
		shape->setVertices(vertices_obj);
		shape->setIndices(indices_obj);
		shape->setNormIndices(norm_indices_obj);
		shape->buildGeometry();
		node->setGeometry(shape);
	}
}