0

I have a problem with my parser. I want to make it so that it can parse only one normal per one vertex. But I am struggling to do so because there are different variations of the .obj files.

For example, if I parse cube.obj, it has only 6 normals and 12 indices. But some .obj files do not have the same amount of normals and vertices but have the same amount of indices and vertices, and I want to parse for every vertex as normal.

I already did a parser, here is a code:

void LoadMeshData(mesh_t* Mesh, char* FileName)
{
    FILE* file = NULL;
    fopen_s(&file, FileName, "r");
    
    std::vector<tex2d> TextureCoords;
    char Line[256];
    while(fgets(Line, 256, (FILE*)file) != NULL)
    {
        int32_t CharIdx = 0;
        char PrevChar = 0;
        char Char = Line[CharIdx];

        while(Char)
        {
            Char = Line[CharIdx++];
            if(Char == '#' || Char == 'm' || Char == 'o' && Char == 'u' || Char == 's') break;
            if((PrevChar == 'v' && Char == 't')) 
            {
                v3 Coords = ParseVertex(Line);
                tex2d UVCoords = V3ToUVs(Coords);
                Mesh->TextureCoords.push_back(UVCoords);
                break;
            }
            if((PrevChar == 'v' && Char == 'n'))
            {
                v3 Normals = ParseVertex(Line);
                Mesh->Normals.push_back(Normals);
                break;
            }

            if((PrevChar == 'v' && Char == ' '))
            {
                v3 Vert = ParseVertex(Line);
                Mesh->Vertices.push_back(Vert);
                break;
            } 
            if((PrevChar == 'f' && Char == ' '))
            {
                face_t Face = {};
                parsed_obj Obj = ParseFace(Line);

                //memcpy(Face.E, Obj.VertexIndices, sizeof(int32_t)*3);
                Mesh->Indices.push_back(Obj.VertexIndices[0]);
                Mesh->Indices.push_back(Obj.VertexIndices[1]);
                Mesh->Indices.push_back(Obj.VertexIndices[2]);
                break;
            }
            PrevChar = Char;
        }
    }
}

And here is examples of some of the mine .obj files:

enter image description here

enter image description here

enter image description here

I am still not that skillful at creating good algorithms, as I am still learning to do so. Is there a good way to make that parser parse for every vertex a normal?

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
Zhukov Artem
  • 331
  • 1
  • 2
  • 12
  • You have tagged C, but the code is C++. And you use the word “normal” without stating any context that would select one of its many meanings. Edit the question to clarify, including using correct language tags and explaining the context of the question. – Eric Postpischil Nov 20 '21 at 09:38
  • Thanks, I totally forget I was using c++. And I hope new changes to the context made it better – Zhukov Artem Nov 20 '21 at 09:43
  • In the Wavefront Object format, assuming coordinates and normals, the indices (e.g. for `f`) can be given in two ways: 1. `1//1` (separate indices for coordinates and normal per vertex), 2. `1` (common index for coordinates _and_ normals). (I know quite good about this as I had to add support for the latter in my `.obj` parser just recently as I was not aware of this before.) :-) However, in the second case, the number of coordinates and normals (`v` and `vN`) must be equal, and you stated that's not the case in your sample. – Scheff's Cat Nov 20 '21 at 12:07
  • Can you provide a small sample `.obj` in source code? – Scheff's Cat Nov 20 '21 at 12:08
  • For the case, that coordinates and normal index have separate indices, and your mesh storage doesn't support this, you have to build a new vertex array where the resp. coordinates and normals are stored in pairs, maybe, with a resp. new index array which refers to them. – Scheff's Cat Nov 20 '21 at 12:16
  • In case of doubts, there is [assimp/assimp ObjFileParser.cpp](https://github.com/assimp/assimp/blob/master/code/AssetLib/Obj/ObjFileParser.cpp) on github where you can have a look at how others did it... ;-) – Scheff's Cat Nov 20 '21 at 12:28

0 Answers0