| 28 | } |
| 29 | |
| 30 | std::vector<CarModel> NFS3::LoadFCE(const std::string &fce_path) { |
| 31 | LOG(INFO) << "Parsing FCE File located at " << fce_path; |
| 32 | glm::quat rotationMatrix = glm::normalize(glm::quat(glm::vec3(-SIMD_PI/2,0,0))); // All Vertices are stored so that the model is rotated 90 degs on X. Remove this at Vert load time. |
| 33 | |
| 34 | std::vector<CarModel> meshes; |
| 35 | |
| 36 | ifstream fce(fce_path, ios::in | ios::binary); |
| 37 | |
| 38 | auto *fceHeader = new FCE::NFS3::HEADER(); |
| 39 | fce.read((char *) fceHeader, sizeof(FCE::NFS3::HEADER)); |
| 40 | |
| 41 | for (uint32_t part_Idx = 0; part_Idx < fceHeader->nParts; ++part_Idx) { |
| 42 | float specularDamper = 0.2f; |
| 43 | float specularReflectivity = 0.02f; |
| 44 | float envReflectivity = 0.4f; |
| 45 | |
| 46 | std::vector<uint32_t> indices; |
| 47 | std::vector<uint32_t> polygonFlags; |
| 48 | std::vector<glm::vec3> vertices; |
| 49 | std::vector<glm::vec3> normals; |
| 50 | std::vector<glm::vec2> uvs; |
| 51 | |
| 52 | std::string part_name(fceHeader->partNames[part_Idx]); |
| 53 | glm::vec3 center = rotationMatrix * glm::vec3(fceHeader->partCoords[part_Idx].x/10, fceHeader->partCoords[part_Idx].y/10, fceHeader->partCoords[part_Idx].z/10); |
| 54 | |
| 55 | auto *partVertices = new FLOATPT[fceHeader->partNumVertices[part_Idx]]; |
| 56 | auto *partNormals = new FLOATPT[fceHeader->partNumVertices[part_Idx]]; |
| 57 | auto *partTriangles = new FCE::TRIANGLE[fceHeader->partNumTriangles[part_Idx]]; |
| 58 | |
| 59 | fce.seekg(sizeof(FCE::NFS3::HEADER) + fceHeader->vertTblOffset + (fceHeader->partFirstVertIndices[part_Idx] * sizeof(FLOATPT)), ios_base::beg); |
| 60 | fce.read((char *) partVertices, fceHeader->partNumVertices[part_Idx] * sizeof(FLOATPT)); |
| 61 | for (uint32_t vert_Idx = 0; vert_Idx < fceHeader->partNumVertices[part_Idx]; ++vert_Idx) { |
| 62 | vertices.emplace_back(rotationMatrix * glm::vec3(partVertices[vert_Idx].x /10, partVertices[vert_Idx].y/10, partVertices[vert_Idx].z/10)); |
| 63 | } |
| 64 | |
| 65 | fce.seekg(sizeof(FCE::NFS3::HEADER) + fceHeader->normTblOffset + (fceHeader->partFirstVertIndices[part_Idx] * sizeof(FLOATPT)), ios_base::beg); |
| 66 | fce.read((char *) partNormals, fceHeader->partNumVertices[part_Idx] * sizeof(FLOATPT)); |
| 67 | for (uint32_t normal_Idx = 0; normal_Idx < fceHeader->partNumVertices[part_Idx]; ++normal_Idx) { |
| 68 | normals.emplace_back(rotationMatrix * glm::vec3(partNormals[normal_Idx].x, partNormals[normal_Idx].y, partNormals[normal_Idx].z)); |
| 69 | } |
| 70 | |
| 71 | fce.seekg(sizeof(FCE::NFS3::HEADER) + fceHeader->triTblOffset + (fceHeader->partFirstTriIndices[part_Idx] * sizeof(FCE::TRIANGLE)), ios_base::beg); |
| 72 | fce.read((char *) partTriangles, fceHeader->partNumTriangles[part_Idx] * sizeof(FCE::TRIANGLE)); |
| 73 | for (uint32_t tri_Idx = 0; tri_Idx < fceHeader->partNumTriangles[part_Idx]; ++tri_Idx) { |
| 74 | polygonFlags.emplace_back(partTriangles[tri_Idx].polygonFlags); |
| 75 | polygonFlags.emplace_back(partTriangles[tri_Idx].polygonFlags); |
| 76 | polygonFlags.emplace_back(partTriangles[tri_Idx].polygonFlags); |
| 77 | indices.emplace_back(partTriangles[tri_Idx].vertex[0]); |
| 78 | indices.emplace_back(partTriangles[tri_Idx].vertex[1]); |
| 79 | indices.emplace_back(partTriangles[tri_Idx].vertex[2]); |
| 80 | uvs.emplace_back(glm::vec2(partTriangles[tri_Idx].uvTable[0], partTriangles[tri_Idx].uvTable[3])); |
| 81 | uvs.emplace_back(glm::vec2(partTriangles[tri_Idx].uvTable[1], partTriangles[tri_Idx].uvTable[4])); |
| 82 | uvs.emplace_back(glm::vec2(partTriangles[tri_Idx].uvTable[2], partTriangles[tri_Idx].uvTable[5])); |
| 83 | } |
| 84 | |
| 85 | meshes.emplace_back(CarModel(part_name, vertices, uvs, normals, indices, polygonFlags, center, specularDamper, specularReflectivity, envReflectivity)); |
| 86 | LOG(INFO) << "Loaded Mesh: " << meshes[part_Idx].m_name << " UVs: " << meshes[part_Idx].m_uvs.size() << " Verts: " << meshes[part_Idx].m_vertices.size() << " Indices: " << meshes[part_Idx].m_vertex_indices.size() << " Normals: " << meshes[part_Idx].m_normals.size(); |
| 87 | |