void LoadMesh(const std::string& filename, std::vector<Vertex>& vertices, std::vector<unsigned int>& indices, const Color& color) { std::ifstream file(filename); assert(file.good() && "Error reading file"); std::vector<Vector3> positions; std::vector<Vector3> normals; std::vector<Vector2> texcoords; std::vector<Face> faces; std::string line; while (std::getline(file, line)) { if (line.empty()) continue; switch (line[0]) { case 'v': ParseVertexAttrib(line, positions, normals, texcoords); break; case 'f': ParseFace(line, faces); break; default: break; } } for (unsigned int f = 0; f < faces.size(); ++f) { auto& face = faces[f]; for (int i = 0; i < 3; ++i) { const IndexTriplet& triplet = face.indices[i]; int posIndex = triplet.positionIndex - 1; const auto& pos = positions[posIndex]; const auto& nor = normals[triplet.normalIndex - 1]; const auto& tex = texcoords[triplet.texcoordIndex - 1]; Vertex vertex; vertex.position = pos; vertex.normal = nor; vertex.color = color; vertices.push_back(vertex); unsigned int index = 3 * f + i; indices.push_back(index); } } }
void ParseLine( const char* line ) { m_line = line; SkipSpace(); switch(*(m_line++)) { case 'f': if (isspace(*(m_line++))) { ParseFace(); } break; case 'v': { char ch = *(m_line++); switch (ch) { case 'n': { ParseVec3(m_normals); return; } case 't': { ParseVec2(m_uvs); return; } default: if (isspace(ch)) { ParseVec3(m_positions); } return; } } } }
ModelData* ModelLoader::LoadModelFile(std::string filePath) { ifstream file; file.open(filePath + ".obj"); if (!file) return 0; string str; while (!file.eof()) { file >> str; if (str == "#" || str == "s") ParseComment(file); else if (str == "v") ParsePosition(file); //position else if (str == "vn") ParseNormal(file); //normal else if (str == "vt") ParseTexCoord(file); //texturkoordinat else if (str == "f") ParseFace(file); //face else if (str == "usemtl") ParseMaterial(file); //material else if (str == "g") ParseGroup(file); //group else if (str == "mtllib") //materialfile { ParseMaterialFile(file, filePath); } str = ""; } //ParseFace2(file); ModelData* model = new ModelData(); for (auto it = m_groups.begin(); it != m_groups.end(); ++it) model->Groups.push_back(it->second); return model; }
/* =============== R_LoadSurfaces =============== */ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) { dsurface_t *in; msurface_t *out; mapVert_t *dv; int *indexes; int count; int numFaces, numMeshes, numTriSurfs, numFlares; int i; numFaces = 0; numMeshes = 0; numTriSurfs = 0; numFlares = 0; in = (dsurface_t *)(fileBase + surfs->fileofs); if (surfs->filelen % sizeof(*in)) ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name); count = surfs->filelen / sizeof(*in); dv = (mapVert_t *)(fileBase + verts->fileofs); if (verts->filelen % sizeof(*dv)) ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name); indexes = (int *)(fileBase + indexLump->fileofs); if ( indexLump->filelen % sizeof(*indexes)) ri.Error (ERR_DROP, "LoadMap: funny lump size in %s",s_worldData.name); out = (struct msurface_s *) ri.Hunk_Alloc ( count * sizeof(*out), qtrue ); s_worldData.surfaces = out; s_worldData.numsurfaces = count; // new bit, the face code on our biggest map requires over 15,000 mallocs, which was no problem on the hunk, // bit hits the zone pretty bad (even the tagFree takes about 9 seconds for that many memblocks), // so special-case pre-alloc enough space for this data (the patches etc can stay as they are)... // int iFaceDataSizeRequired = 0; for ( i = 0 ; i < count ; i++, in++) { switch ( LittleLong( in->surfaceType ) ) { case MST_PLANAR: int sfaceSize = ( int ) &((srfSurfaceFace_t *)0)->points[LittleLong(in->numVerts)]; sfaceSize += sizeof( int ) * LittleLong(in->numIndexes); iFaceDataSizeRequired += sfaceSize; break; } } in -= count; // back it up, ready for loop-proper // since this ptr is to hunk data, I can pass it in and have it advanced without worrying about losing // the original alloc ptr... // byte *pFaceDataBuffer = (byte *)ri.Hunk_Alloc( iFaceDataSizeRequired, qtrue ); // now do regular loop... // for ( i = 0 ; i < count ; i++, in++, out++ ) { switch ( LittleLong( in->surfaceType ) ) { case MST_PATCH: ParseMesh ( in, dv, out); numMeshes++; break; case MST_TRIANGLE_SOUP: ParseTriSurf( in, dv, out, indexes ); numTriSurfs++; break; case MST_PLANAR: ParseFace( in, dv, out, indexes, pFaceDataBuffer ); numFaces++; break; case MST_FLARE: ParseFlare( in, dv, out, indexes ); numFlares++; break; default: ri.Error( ERR_DROP, "Bad surfaceType" ); } } ri.Printf( PRINT_ALL, "...loaded %d faces, %i meshes, %i trisurfs, %i flares\n", numFaces, numMeshes, numTriSurfs, numFlares ); }