Ejemplo n.º 1
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;

}
Ejemplo n.º 2
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" );
	}
}
Ejemplo n.º 3
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();
}
bool RTRModel::loadMaterialLibraryFromMtlFile(const QString& filePath)
{
	QFile mtlFile(filePath);
	if (!mtlFile.open(QIODevice::ReadOnly))
	{
		return false;
	}
	QTextStream mtlFileStream(&mtlFile);
	QString currentMaterialName;
	RTRMaterial* currentMaterial = NULL;
	while (!mtlFileStream.atEnd())
	{
		QString line = mtlFileStream.readLine().trimmed();
		if (line.isEmpty()) continue;
		if (line[0] == '#')
		{
			qDebug() << "Ignoring Comment Line:" << line;
			continue;
		}
		QStringList param = line.split(' ', QString::SkipEmptyParts);
		QString command = param[0];
		command = command.toLower();
		param.removeFirst();
		if (command == "newmtl")
		{
			if (currentMaterial != NULL)
			{
				materialLibrary.insert(currentMaterialName, currentMaterial);
			}
			currentMaterialName = param[0];
			currentMaterial = new RTRMaterial();
		}
		else
		{
			if (currentMaterial == NULL)
			{
				mtlFile.close();
				return false;
			}
            if (command == "kd")
            {
                currentMaterial->diffuse = RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble());
                currentMaterial->setColorProperty("diffuse", RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble()));
            }
            else if (command == "map_kd")
                currentMaterial->setTextureProperty("diffuse", modelPath + "/" + param[0]);
            else if (command == "ka")
                currentMaterial->setColorProperty("ambient", RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble()));
            else if (command == "ks")
                currentMaterial->setColorProperty("specular", RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble()));
            else if (command == "reflection_rate")
            {
                currentMaterial->reflectionRate = param[0].toDouble();
                currentMaterial->setColorProperty("reflection_rate", RTRColor(param[0].toDouble(), param[0].toDouble(), param[0].toDouble()));
            }
            else if (command == "reflection_color")
            {
                currentMaterial->reflectionColor = RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble());
                currentMaterial->setColorProperty("reflection_color", RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble()));
            }
            else if (command == "reflection_glossiness")
                currentMaterial->setColorProperty("reflection_glossiness", RTRColor(param[0].toDouble(), param[0].toDouble(), param[0].toDouble()));
            else if (command == "refraction_rate")
            {
                currentMaterial->refractionRate = param[0].toDouble();
                currentMaterial->setColorProperty("refraction_rate", RTRColor(param[0].toDouble(), param[0].toDouble(), param[0].toDouble()));
            }
            else if (command == "refraction_index")
            {
                currentMaterial->refractionIndex = param[0].toDouble();
                currentMaterial->setColorProperty("refraction_index", RTRColor(param[0].toDouble(), param[0].toDouble(), param[0].toDouble()));
            }
            else if (command == "refraction_color")
            {
                currentMaterial->refractionColor = RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble());
                currentMaterial->setColorProperty("refraction_color", RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble()));
            }
            else if (command == "refraction_glossiness")
                currentMaterial->setColorProperty("refraction_glossiness", RTRColor(param[0].toDouble(), param[0].toDouble(), param[0].toDouble()));
            else if (command == "fod_aperture")
                currentMaterial->setColorProperty("fod_aperture", RTRColor(param[0].toDouble(), param[0].toDouble(), param[0].toDouble()));
            else if (command == "fod_focus")
                currentMaterial->setColorProperty("fod_focus", RTRColor(param[0].toDouble(), param[0].toDouble(), param[0].toDouble()));
            else if (command == "camera_position")
                currentMaterial->setColorProperty("camera_position", RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble()));
            else if (command == "camera_angle")
                currentMaterial->setColorProperty("camera_angle", RTRColor(param[0].toDouble(), param[1].toDouble(), param[2].toDouble()));
            else if (command == "image_distance")
                currentMaterial->setColorProperty("image_distance", RTRColor(param[0].toDouble(), param[0].toDouble(), param[0].toDouble()));
            else if (command == "emission_strength")
                currentMaterial->emissionStrength = param[0].toDouble();
		}
	}
	if (currentMaterial != NULL)
	{
		materialLibrary.insert(currentMaterialName, currentMaterial);
	}
	mtlFile.close();
	return true;
}
Ejemplo n.º 5
0
void testApp::update() {
    
    simpl = (int)(abs(fsimpl));
    fsimpl = simpl;
    depthThreshhold = (int)(abs(fdepth));
    fdepth = depthThreshhold;
    if (!fileq.empty()){                
        filecounter--;
        
        
        //statusText += ("processed " + fileq.back() +"\n");
        doneFiles.push_back("processed " + fileq.back() +"\n");
        if (doneFiles.size()>=5) doneFiles.pop_front();
        
        kinect.readCompressedPng(fileq.back(), spix);           
        
        
        
        int height = 480;
        int width = 640;
        
        //this section is modified from the ofxRGBDepth renderer so as to not require opencv camera intrinsics. 
        ofFile mtlFile("/tmp/rgbdsharedmaterial.mtl", ofFile::WriteOnly);
        mtlFile << "newmtl rgbdshared" <<endl; //define shared material. simplifies workflow in blender. 
        mtlFile << "illum 1" <<endl; //no specular.
        mtlFile.close();
        
        ofFile file("/tmp/rgbd_"+ofToString(filecounter,3)+".obj", ofFile::WriteOnly);
        float fx = tanf(ofDegToRad(fov.x) / 2) * 2;
        float fy = tanf(ofDegToRad(fov.y) / 2) * 2;
        file << "mtllib rgbdsharedmaterial.mtl" << endl;
        file << "usemtl rgbdshared" << endl; 
        
        file << "#vertices" << endl;
        
        for (int y = 0; y < height; y+=1){
            for (int x = 0; x<width; x+=1){
                unsigned short z = spix[x+y*width];
                float xReal=(((float)x-320) / 640.) * z * fx;
                float yReal=(((float)y-240) / 480.) * z * fy;
                //blender coordinates are weird so we invert everything here. 
                //this will orient for a blender camera at 0,0,0 with x rotation at 90. 
                file << "v " << ofToString((float)xReal/32.) << " " << ofToString(-(float)yReal/32.) << " " << ofToString((float)(-spix[x+y*width]/32.)) << endl;
                
            }
        }
        
        file << "#faces" << endl;
        int coordx, coordy=0;
        
        for (int y = 0; y<height-simpl; y+=simpl){
            for (int x=0; x<width-simpl; x+=simpl){
                if (
                    
                    
                    (spix[x+y*width] > 0)
                    &&(abs(spix[x+y*width] - spix[(x+simpl)+y*width]) <= depthThreshhold)
                    &&(abs(spix[x+y*width] - spix[x+(y+simpl)*width]) <= depthThreshhold)
                    &&(abs(spix[(x+simpl)+y*width] - spix[x+(y+simpl)*width]) <= depthThreshhold)
                    
                    &&(abs(spix[(x+simpl)+y*width] - spix[(x+simpl)+(y+simpl)*width]) <= depthThreshhold)
                    &&(abs(spix[(x+simpl)+y*width] - spix[x+(y+simpl)*width]) <= depthThreshhold)
                    &&(abs(spix[(x+simpl)+(y+simpl)*width] - spix[x+(y+simpl)*width]) <= depthThreshhold)
                    ){
                    file << "f " << ofToString(1+x+y*width) << " " << ofToString(1+(x+simpl)+y*width)<< " " << ofToString(1+x+(y+simpl)*width) << endl;
                    file << "f " << ofToString(1+(x+simpl)+y*(width))<< " " << ofToString(1+(x+simpl)+(y+simpl)*width)<< " " << ofToString(1+x+(y+simpl)*(width)) << endl;
                    
                }
                
            }
            
        }
        file.close();
        if (fileq.size()==1) doneFiles.push_back("done!");
        fileq.pop_back();
    } 
    
}