IndexedModel OBJModel::ToIndexedModel() { IndexedModel result; IndexedModel normalModel; unsigned int numIndices = OBJIndices.size(); std::vector<OBJIndex*> indexLookup; for(unsigned int i = 0; i < numIndices; i++) indexLookup.push_back(&OBJIndices[i]); std::sort(indexLookup.begin(), indexLookup.end(), CompareOBJIndexPtr); std::map<OBJIndex, unsigned int> normalModelIndexMap; std::map<unsigned int, unsigned int> indexMap; for(unsigned int i = 0; i < numIndices; i++) { OBJIndex* currentIndex = &OBJIndices[i]; glm::vec3 currentPosition = vertices[currentIndex->vertexIndex]; glm::vec2 currentTexCoord; glm::vec3 currentNormal; if(hasUVs) currentTexCoord = uvs[currentIndex->uvIndex]; else currentTexCoord = glm::vec2(0,0); if(hasNormals) currentNormal = normals[currentIndex->normalIndex]; else currentNormal = glm::vec3(0,0,0); unsigned int normalModelIndex; unsigned int resultModelIndex; //Create model to properly generate normals on std::map<OBJIndex, unsigned int>::iterator it = normalModelIndexMap.find(*currentIndex); if(it == normalModelIndexMap.end()) { normalModelIndex = normalModel.positions.size(); normalModelIndexMap.insert(std::pair<OBJIndex, unsigned int>(*currentIndex, normalModelIndex)); normalModel.positions.push_back(currentPosition); normalModel.texCoords.push_back(currentTexCoord); normalModel.normals.push_back(currentNormal); } else normalModelIndex = it->second; //Create model which properly separates texture coordinates unsigned int previousVertexLocation = FindLastVertexIndex(indexLookup, currentIndex, result); if(previousVertexLocation == (unsigned int)-1) { resultModelIndex = result.positions.size(); result.positions.push_back(currentPosition); result.texCoords.push_back(currentTexCoord); result.normals.push_back(currentNormal); } else resultModelIndex = previousVertexLocation; normalModel.indices.push_back(normalModelIndex); result.indices.push_back(resultModelIndex); indexMap.insert(std::pair<unsigned int, unsigned int>(resultModelIndex, normalModelIndex)); } if(!hasNormals) { normalModel.CalcNormals(); for(unsigned int i = 0; i < result.positions.size(); i++) result.normals[i] = normalModel.normals[indexMap[i]]; } return result; };
std::vector<IndexedModel> OBJModel::ToIndexedModel() { GLint vertexPos = 0, uvPos = 0; for each (Group group in GroupList) { IndexedModel result; IndexedModel normalModel; unsigned int numIndices = group.OBJIndices.size(); std::vector<OBJIndex*> indexLookup; for (unsigned int i = 0; i < numIndices; i++) indexLookup.push_back(&group.OBJIndices[i]); std::sort(indexLookup.begin(), indexLookup.end(), CompareOBJIndexPtr); std::map<OBJIndex, unsigned int> normalModelIndexMap; std::map<unsigned int, unsigned int> indexMap; vertexPos += (group.id > 0) ? GroupList[group.id - 1].vertices.size() : 0; uvPos += (group.id > 0) ? GroupList[group.id - 1].uvs.size() : 0; for (unsigned int i = 0; i < numIndices; i++) { OBJIndex* currentIndex = &group.OBJIndices[i]; glm::vec3 currentPosition = group.vertices[currentIndex->vertexIndex - vertexPos]; glm::vec2 currentTexCoord; glm::vec3 currentNormal; if (group.hasUVs) currentTexCoord = group.uvs[currentIndex->uvIndex - uvPos]; else currentNormal = glm::vec3(0, 0, 0); unsigned int normalModelIndex; unsigned int resultModelIndex; std::map<OBJIndex, unsigned int>::iterator it = normalModelIndexMap.find(*currentIndex); if (it == normalModelIndexMap.end()) { normalModelIndex = normalModel.positions.size(); normalModelIndexMap.insert(std::pair<OBJIndex, unsigned int>(*currentIndex, normalModelIndex)); normalModel.positions.push_back(currentPosition); normalModel.texCoords.push_back(currentTexCoord); normalModel.normals.push_back(currentNormal); } else normalModelIndex = it->second; unsigned int previousVertexLocation = FindLastVertexIndex(group, indexLookup, currentIndex, result); if (previousVertexLocation == (unsigned int)-1) { resultModelIndex = result.positions.size(); result.positions.push_back(currentPosition); result.texCoords.push_back(currentTexCoord); result.normals.push_back(currentNormal); } else resultModelIndex = previousVertexLocation; normalModel.indices.push_back(normalModelIndex); result.indices.push_back(resultModelIndex); indexMap.insert(std::pair<unsigned int, unsigned int>(resultModelIndex, normalModelIndex)); } if (!group.hasNormals) { normalModel.CalcNormals(); for (unsigned int i = 0; i < result.positions.size(); i++) { result.normals[i] = normalModel.normals[indexMap[i]]; } } result.hasUVs = group.hasUVs; result.hasNormals = group.hasNormals; IndexedModelList.push_back(result); }