MCPcopy Create free account
hub / github.com/OpenNFS/OpenNFS / LoadFCE

Method LoadFCE

src/Loaders/nfs3_loader.cpp:30–97  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

28}
29
30std::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

Callers

nothing calls this directly

Calls 1

CarModelClass · 0.85

Tested by

no test coverage detected