cparsingmeshwavefront

Why doesn't my wavefront obj file parser order vertices properly?


Parsing normals and vertices renders only the front side properly. This is just vertices, code for normals works the same way:

for(i = 0; i < vertexsize; i += 3){
    verticesind[i] = verticesout[vertexindices[i] - 1];
    verticesind[i + 1] = verticesout[vertexindices[i + 1] - 1];
    verticesind[i + 2] = verticesout[vertexindices[i + 2] - 1];
    verticessize += sizeof(verticesind[i]) + sizeof(verticesind[i + 1]) + sizeof(vertices[i + 2]);
}

model.obj:

# Blender v2.93.8 OBJ File: ''
# www.blender.org
o Cube
v 0.500000 0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
v 0.500000 0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v -0.500000 0.500000 0.500000
v -0.500000 -0.500000 0.500000
vt 0.875000 0.500000
vt 0.625000 0.750000
vt 0.625000 0.500000
vt 0.375000 1.000000
vt 0.375000 0.750000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.375000 0.000000
vt 0.375000 0.500000
vt 0.125000 0.750000
vt 0.125000 0.500000
vt 0.625000 0.250000
vt 0.875000 0.750000
vt 0.625000 1.000000
vn 0.0000 1.0000 0.0000
vn 0.0000 0.0000 1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 0.0000 -1.0000
s off
f 5/1/1 3/2/1 1/3/1
f 3/2/2 8/4/2 4/5/2
f 7/6/3 6/7/3 8/8/3
f 2/9/4 8/10/4 6/11/4
f 1/3/5 4/5/5 2/9/5
f 5/12/6 2/9/6 6/7/6
f 5/1/1 7/13/1 3/2/1
f 3/2/2 7/14/2 8/4/2
f 7/6/3 5/12/3 6/7/3
f 2/9/4 4/5/4 8/10/4
f 1/3/5 3/2/5 4/5/5
f 5/12/6 1/3/6 2/9/6

One of the top triangles should be:

-0.5, 0.5, -0.5,
 0.5, 0.5,  0.5,
 0.5, 0.5, -0.5

A full triangle, but they get turned into:

-0.5, -0.5, 0.5,
-0.5,  0.5, 0.5,
 0.5, -0.5, 0.5

My function:

int load_obj(const char* filename, float* vertices, float* texcoords, float* normals, unsigned int* vertexindexsize, unsigned int* texcoordindexsize, unsigned int* normalindexsize){
    FILE* file = fopen(filename, "r");
    char lineheader[128];
    int res;
    int i = 0;
    int f = 0;
    int d = 0;
    int g = 0;
    unsigned int vertexsize = 0;
    unsigned int texcoordsize = 0;
    unsigned int normalsize = 0;
    unsigned int verticessize = 0;
    unsigned int texturecoordsize = 0;
    unsigned int normalssize = 0;
    float verticesout[500];
    float texcoordsout[500];
    float normalsout[500];
    float verticesind[500];
    float texturecoordsind[500];
    float normalsind[500];
    unsigned int vertexindex[3];
    unsigned int texindex[3];
    unsigned int normalindex[3];
    vec3 vertex;
    vec2 texcoord;
    vec3 normal;
    int vertexindices[500];
    int texindices[500];
    int normalindices[500];
    if(file == NULL){
        printf("Failed to open file!\n");
        return 1;
    }
    while(1){
        res = fscanf(file, "%s", lineheader);
        if(res == EOF){
            break;
        }
        if(strcmp(lineheader, "v") == 0){
            fscanf(file, "%f %f %f\n", &vertex[0], &vertex[1], &vertex[2]);
            verticesout[i] = vertex[0];
            verticesout[i + 1] = vertex[1];
            verticesout[i + 2] = vertex[2];
            i += 3;
        }else if(strcmp(lineheader, "vt") == 0){
            fscanf(file, "%f %f\n", &texcoord[0], &texcoord[1]);
            texcoordsout[f] = texcoord[0];
            texcoordsout[f + 1] = texcoord[1];
            f += 2;
        }else if(strcmp(lineheader, "vn") == 0){
            fscanf(file, "%f %f %f\n", &normal[0], &normal[1], &normal[2]);
            normalsout[d] = normal[0];
            normalsout[d + 1] = normal[1];
            normalsout[d + 2] = normal[2];
            d += 3;
        }else if(strcmp(lineheader, "f") == 0){
            fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vertexindex[0], &texindex[0], &normalindex[0], &vertexindex[1], &texindex[1], &normalindex[1], &vertexindex[2], &texindex[2], &normalindex[2]);
            vertexindices[g] = vertexindex[0];
            vertexindices[g + 1] = vertexindex[1];
            vertexindices[g + 2] = vertexindex[2];
        vertexsize += 3;
            texindices[g] = texindex[0];
            texindices[g + 1] = texindex[1];
            texindices[g + 2] = texindex[2];
        texcoordsize += 3;
            normalindices[g] = normalindex[0];
            normalindices[g + 1] = normalindex[1];
            normalindices[g + 2] = normalindex[2];
        normalsize += 3;
            g += 3;
        }
    }
    for(i = 0; i < vertexsize; i += 3){
        verticesind[i] = verticesout[vertexindices[i] - 1];
        verticesind[i + 1] = verticesout[vertexindices[i + 1] - 1];
        verticesind[i + 2] = verticesout[vertexindices[i + 2] - 1];
        verticessize += sizeof(verticesind[i]) + sizeof(verticesind[i + 1]) + sizeof(vertices[i + 2]);
    }
    for(i = 0; i < texcoordsize; i++){
        texturecoordsind[i] = texcoordsout[texindices[i] - 1];
        texturecoordsize += sizeof(texturecoordsind[i]);
    }
    for(i = 0; i < normalsize; i += 3){
        normalsind[i] = normalsout[normalindices[i] - 1];
        normalsind[i + 1] = normalsout[normalindices[i + 1] - 1];
        normalsind[i + 2] = normalsout[normalindices[i + 2] - 1];
        normalssize += sizeof(normalsind[i]) + sizeof(normalsind[i + 1]) + sizeof(normalsind[i + 2]);
    }
    memcpy(vertices, verticesind, sizeof(verticesind));
    memcpy(texcoords, texturecoordsind, sizeof(texturecoordsind));
    memcpy(normals, normalsind, sizeof(normalsind));
    *vertexindexsize = verticessize;
    *texcoordindexsize = texturecoordsize;
    *normalindexsize = normalssize;
    return 0;
}

Solution

  • I changed the function a bit, as it didn't take use of the indices correctly:

    for(i = 0; i < vertexsize; i++){
          verticesind[i * 3] = verticesout[(vertexindices[i] - 1) * 3];
          verticesind[i * 3 + 1] = verticesout[(vertexindices[i] - 1) * 3 + 1];
          verticesind[i * 3 + 2] = verticesout[(vertexindices[i] - 1) * 3 + 2];
          verticessize += sizeof(verticesind[i]) * 3;
    }
    

    Now it loads the vertices and normals properly.