bool MyObjLoader::LoadObjModel(bool isRHCoordSys, bool computeNormals) { HRESULT hr = 0; std::wifstream fileIn (filename.c_str()); //Open file std::wstring meshMatLib; //String to hold our obj material library filename //Arrays to store our model's information std::vector<DWORD> indices; std::vector<float3> vertPos; std::vector<float3> vertNorm; std::vector<float2> vertTexCoord; std::vector<std::wstring> meshMaterials; //Vertex definition indices std::vector<int> vertPosIndex; std::vector<int> vertNormIndex; std::vector<int> vertTCIndex; //Make sure we have a default if no tex coords or normals are defined bool hasTexCoord = false; bool hasNorm = false; //Temp variables to store into vectors std::wstring meshMaterialsTemp; int vertPosIndexTemp; int vertNormIndexTemp; int vertTCIndexTemp; wchar_t checkChar; //The variable we will use to store one char from file at a time std::wstring face; //Holds the string containing our face vertices int vIndex = 0; //Keep track of our vertex index count int triangleCount = 0; //Total Triangles int totalVerts = 0; int meshTriangles = 0; //Check to see if the file was opened if (fileIn) { while(fileIn) { checkChar = fileIn.get(); //Get next char switch (checkChar) { case '#': checkChar = fileIn.get(); while(checkChar != '\n') checkChar = fileIn.get(); break; case 'v': //Get Vertex Descriptions checkChar = fileIn.get(); if(checkChar == ' ') //v - vert position { float vz, vy, vx; fileIn >> vx >> vy >> vz; //Store the next three types if(isRHCoordSys) //If model is from an RH Coord System vertPos.push_back(float3( vx, vy, vz * -1.0f)); //Invert the Z axis else vertPos.push_back(float3( vx, vy, vz)); } if(checkChar == 't') //vt - vert tex coords { float vtcu, vtcv; fileIn >> vtcu >> vtcv; //Store next two types if(isRHCoordSys) //If model is from an RH Coord System vertTexCoord.push_back(float2(vtcu, 1.0f-vtcv)); //Reverse the "v" axis else vertTexCoord.push_back(float2(vtcu, vtcv)); hasTexCoord = true; //We know the model uses texture coords } //Since we compute the normals later, we don't need to check for normals //In the file, but i'll do it here anyway if(checkChar == 'n') //vn - vert normal { float vnx, vny, vnz; fileIn >> vnx >> vny >> vnz; //Store next three types if(isRHCoordSys) //If model is from an RH Coord System vertNorm.push_back(float3( vnx, vny, vnz * -1.0f )); //Invert the Z axis else vertNorm.push_back(float3( vnx, vny, vnz )); hasNorm = true; //We know the model defines normals } break; //New group (Subset) case 'g': //g - defines a group checkChar = fileIn.get(); if(checkChar == ' ') { subsetIndexStart.push_back(vIndex); //Start index for this subset subsetCount++; } break; //Get Face Index case 'f': //f - defines the faces checkChar = fileIn.get(); if(checkChar == ' ') { face = L""; std::wstring VertDef; //Holds one vertex definition at a time triangleCount = 0; checkChar = fileIn.get(); while(checkChar != '\n') { face += checkChar; //Add the char to our face string checkChar = fileIn.get(); //Get the next Character if(checkChar == ' ') //If its a space... triangleCount++; //Increase our triangle count } //Check for space at the end of our face string if(face[face.length()-1] == ' ') triangleCount--; //Each space adds to our triangle count triangleCount -= 1; //Ever vertex in the face AFTER the first two are new faces std::wstringstream ss(face); if(face.length() > 0) { int firstVIndex, lastVIndex; //Holds the first and last vertice's index for(int i = 0; i < 3; ++i) //First three vertices (first triangle) { ss >> VertDef; //Get vertex definition (vPos/vTexCoord/vNorm) std::wstring vertPart; int whichPart = 0; //(vPos, vTexCoord, or vNorm) //Parse this string for(uint32 j = 0; j < VertDef.length(); ++j) { if(VertDef[j] != '/') //If there is no divider "/", add a char to our vertPart vertPart += VertDef[j]; //If the current char is a divider "/", or its the last character in the string if(VertDef[j] == '/' || j == VertDef.length()-1) { std::wistringstream wstringToInt(vertPart); //Used to convert wstring to int if(whichPart == 0) //If vPos { wstringToInt >> vertPosIndexTemp; vertPosIndexTemp -= 1; //subtract one since c++ arrays start with 0, and obj start with 1 //Check to see if the vert pos was the only thing specified if(j == VertDef.length()-1) { vertNormIndexTemp = 0; vertTCIndexTemp = 0; } } else if(whichPart == 1) //If vTexCoord { if(vertPart != L"") //Check to see if there even is a tex coord { wstringToInt >> vertTCIndexTemp; vertTCIndexTemp -= 1; //subtract one since c++ arrays start with 0, and obj start with 1 } else //If there is no tex coord, make a default
bool LoadObjModel(std::wstring filename, ID3D11Buffer** vertBuff, ID3D11Buffer** indexBuff, ID3D11Device * device, UINT & verCnt, bool bComputeNormals , bool bAverageNormals , bool bComputeTangents , bool bAverageTangents ) { HRESULT hr = 0; std::wifstream fileIn(filename.c_str()); //Open file //Arrays to store our model's information std::vector<DWORD> indices; std::vector<XMFLOAT3> vertPos; std::vector<XMFLOAT3> vertNorm; std::vector<XMFLOAT2> vertTexCoord; //Vertex definition indices std::vector<int> vertPosIndex; std::vector<int> vertNormIndex; std::vector<int> vertTCIndex; //Make sure we have a default if no tex coords or normals are defined bool hasTexCoord = false; bool hasNorm = false; //Temp variables to store into vectors int vertPosIndexTemp; int vertNormIndexTemp; int vertTCIndexTemp; wchar_t checkChar; //The variable we will use to store one char from file at a time std::wstring face; //Holds the string containing our face vertices int vIndex = 0; //Keep track of our vertex index count int triangleCount = 0; //Total Triangles int totalVerts = 0; int meshTriangles = 0; //Check to see if the file was opened if (fileIn) { while (fileIn) { checkChar = fileIn.get(); switch (checkChar) { case '#': checkChar = fileIn.get(); while (checkChar != '\n') checkChar = fileIn.get(); break; case 'v': checkChar = fileIn.get(); if (checkChar == ' ') { float vz, vy, vx; fileIn >> vx >> vy >> vz; vertPos.push_back(XMFLOAT3(vx, vy, vz * -1.0f)); } if (checkChar == 't') { float vtcu, vtcv; fileIn >> vtcu >> vtcv; vertTexCoord.push_back(XMFLOAT2(vtcu, 1.0f - vtcv)); hasTexCoord = true; } if (checkChar == 'n') { float vnx, vny, vnz; fileIn >> vnx >> vny >> vnz; vertNorm.push_back(XMFLOAT3(vnx, vny, -vnz)); hasNorm = true; } break; case 'f': checkChar = fileIn.get(); if (checkChar == ' ') { face = L""; std::wstring VertDef; triangleCount = 0; checkChar = fileIn.get(); while (checkChar != '\n') { face += checkChar; checkChar = fileIn.get(); if (checkChar == ' ') triangleCount++; } if (face[face.length() - 1] == ' ') triangleCount--; triangleCount -= 1; std::wstringstream ss(face); if (face.length() > 0) { int firstVIndex, lastVIndex; //Holds the first and last vertice's index for (int i = 0; i < 3; ++i) //First three vertices (first triangle) { ss >> VertDef; //Get vertex definition (vPos/vTexCoord/vNorm) std::wstring vertPart; int whichPart = 0; //(vPos, vTexCoord, or vNorm) //Parse this string for (int j = 0; j < VertDef.length(); ++j) { if (VertDef[j] != '/') //If there is no divider "/", add a char to our vertPart vertPart += VertDef[j]; //If the current char is a divider "/", or its the last character in the string if (VertDef[j] == '/' || j == VertDef.length() - 1) { std::wistringstream wstringToInt(vertPart); //Used to convert wstring to int if (whichPart == 0) //If vPos { wstringToInt >> vertPosIndexTemp; vertPosIndexTemp -= 1; //subtract one since c++ arrays start with 0, and obj start with 1 //Check to see if the vert pos was the only thing specified if (j == VertDef.length() - 1) { vertNormIndexTemp = 0; vertTCIndexTemp = 0; } } else if (whichPart == 1) //If vTexCoord { if (vertPart != L"") //Check to see if there even is a tex coord { wstringToInt >> vertTCIndexTemp; vertTCIndexTemp -= 1; //subtract one since c++ arrays start with 0, and obj start with 1 } else //If there is no tex coord, make a default
bool Game::LoadObjModel(std::wstring filename, //.obj filename ID3D11Buffer** vertBuff, //mesh vertex buffer ID3D11Buffer** indexBuff, //mesh index buffer std::vector<int>& subsetIndexStart, //start index of each subset std::vector<int>& subsetMaterialArray, //index value of material for each subset std::vector<SurfaceMaterial>& material, //vector of material structures int& subsetCount, //Number of subsets in mesh bool isRHCoordSys, //true if model was created in right hand coord system bool computeNormals) //true to compute the normals, false to use the files normals { std::wifstream fileIn(filename.c_str()); //Open file specified on function call std::wstring meshMatLib; //String to hold our obj material library filename //Dynamic arrays to store our model's information std::vector<DWORD> indices; std::vector<XMFLOAT3> vertPos; //vertices in obj file std::vector<XMFLOAT3> vertNorm; //vertex normals in obj file std::vector<XMFLOAT2> vertTexCoord; //text coordinates in obj file std::vector<std::wstring> meshMaterials; //different materials in obj file //Vertex definition indices std::vector<int> vertPosIndex; std::vector<int> vertNormIndex; std::vector<int> vertTCIndex; //Make sure we have a default if no tex coords or normals are defined bool hasTexCoord = false; bool hasNorm = false; //Temp variables to store into vectors std::wstring meshMaterialsTemp; int vertPosIndexTemp; int vertNormIndexTemp; int vertTCIndexTemp; wchar_t checkChar; //The variable we will use to store one char from file at a time std::wstring face; //Holds the string containing our face vertices int vIndex = 0; //Keep track of our vertex index count - store on console int triangleCount = 0; //Total triangles int totalVerts = 0; //Total vertices int meshTriangles = 0; if (fileIn) //if the file name is valid { while (fileIn) { checkChar = fileIn.get(); //Get next char switch (checkChar) //change to check string? { case '#': //skip comments, check char again when new line is reached checkChar = fileIn.get(); while (checkChar != '\n') checkChar = fileIn.get(); break; case 'v': //Get Vertex Descriptions checkChar = fileIn.get(); if (checkChar == ' ') //v - vert position { float vz, vy, vx; fileIn >> vx >> vy >> vz; //Store the next three types if (isRHCoordSys) //If model is from an RH Coord System vertPos.push_back(XMFLOAT3(vx, vy, vz * -1.0f)); //Invert the Z axis else vertPos.push_back(XMFLOAT3(vx, vy, vz)); } if (checkChar == 't') //vt - vert tex coords { float vtcu, vtcv; fileIn >> vtcu >> vtcv; //Store next two types if (isRHCoordSys) //If model is from an RH Coord System vertTexCoord.push_back(XMFLOAT2(vtcu, 1.0f - vtcv)); //Reverse the "v" axis else vertTexCoord.push_back(XMFLOAT2(vtcu, vtcv)); hasTexCoord = true; //We know the model uses texture coords } if (checkChar == 'n') //vn - vert normal { float vnx, vny, vnz; fileIn >> vnx >> vny >> vnz; //Store next three types if (isRHCoordSys) //If model is from an RH Coord System vertNorm.push_back(XMFLOAT3(vnx, vny, vnz * -1.0f)); //Invert the Z axis else vertNorm.push_back(XMFLOAT3(vnx, vny, vnz)); hasNorm = true; //We know the model defines normals } break; //New group (Subset) case 'g': //g - defines a group checkChar = fileIn.get(); if (checkChar == ' ') { subsetIndexStart.push_back(vIndex); //Start index for this subset subsetCount++; } break; case 'm': //mtllib - material library filename //Store the material libraries file name fileIn >> meshMatLib; break; case 'u': //usemtl - which material to use meshMaterialsTemp = L""; //Make sure this is cleared fileIn >> meshMaterialsTemp; //Get next type (string) meshMaterials.push_back(meshMaterialsTemp); default: break; case 'f': //f - defines the faces checkChar = fileIn.get(); if (checkChar == ' ') { face = L""; std::wstring VertDef; //Holds one vertex definition at a time triangleCount = 0; checkChar = fileIn.get(); while (checkChar != '\n') { face += checkChar; //Add the char to our face string checkChar = fileIn.get(); //Get the next Character if (checkChar == ' ') //If its a space... triangleCount++; //Increase our triangle count } //Check for space at the end of our face string if (face[face.length() - 1] == ' ') triangleCount--; //Each space adds to our triangle count triangleCount -= 1; //Ever vertex in the face AFTER the first two are new faces std::wstringstream ss(face); if (face.length() > 0) { int firstVIndex, lastVIndex; //Holds the first and last vertice's index for (int i = 0; i < 3; ++i) //First three vertices (first triangle) { ss >> VertDef; //Get vertex definition (vPos/vTexCoord/vNorm) std::wstring vertPart; int whichPart = 0; //(vPos, vTexCoord, or vNorm) //Parse this string for (int j = 0; j < VertDef.length(); ++j) { if (VertDef[j] != '/') //If there is no divider "/", add a char to our vertPart vertPart += VertDef[j]; //If the current char is a divider "/", or its the last character in the string if (VertDef[j] == '/' || j == VertDef.length() - 1) { std::wistringstream wstringToInt(vertPart); //Used to convert wstring to int if (whichPart == 0) //If vPos { wstringToInt >> vertPosIndexTemp; vertPosIndexTemp -= 1; //subtract one since c++ arrays start with 0, and obj start with 1 //Check to see if the vert pos was the only thing specified if (j == VertDef.length() - 1) { vertNormIndexTemp = 0; vertTCIndexTemp = 0; } } else if (whichPart == 1) //If vTexCoord { if (vertPart != L"") //Check to see if there even is a tex coord { wstringToInt >> vertTCIndexTemp; vertTCIndexTemp -= 1; //subtract one since c++ arrays start with 0, and obj start with 1 } else //If there is no tex coord, make a default