#include #include #include #include #include "wavefrontobj.h" #define OBJ_LINE_BUFFER_SIZE 256 /** * * ADJUSTMENT NEEDED FOR * - Textures * - Face Definitions other than vertex/texture/normal * - Vertex positions including w * - Any faces using vertices yet to be defined * (File is read top to bottom. A face using a vertex * defined underneath it in the file will not work) * */ ParsedObjFile readObjFile(char* path) { ParsedObjFile parsedFile; FILE* fp = fopen(path, "r"); if (fp == NULL) { fprintf(stderr, "File could not be opened: %s", path); parsedFile.faces = NULL; parsedFile.length = 0; } uint numVertices = 0; uint numVertexNormals = 0; uint numFaces = 0; uint numTextureCoords = 0; char buf[OBJ_LINE_BUFFER_SIZE]; while (fgets(buf, OBJ_LINE_BUFFER_SIZE, fp)) { if (buf[0] == 'v') { if (buf[1] == ' ') { numVertices++; } else if (buf[1] == 't') { numTextureCoords++; } else if (buf[1] == 'n') { numVertexNormals++; } } if (buf[0] == 'f') { int numSpaces = 0; for (int i = 0; i < strlen(buf); i++) { if (buf[i] == ' ') { numSpaces++; } } numFaces += numSpaces - 2; } } // printf("Vertices: %d\nFaces: %d\nNormals:%d\nTextures:%d\n", numVertices, numFaces, numVertexNormals, numTextureCoords); vec3* vertices = (vec3*) malloc(sizeof(vec3) * numVertices); vec3* normals = (vec3*) malloc(sizeof(vec3) * numVertexNormals); face* faces = (face*) malloc(sizeof(face) * numFaces); parsedFile.faces = faces; parsedFile.length = numFaces; rewind(fp); uint curVertex = 0; uint curNormal = 0; uint curFace = 0; while (fgets(buf, OBJ_LINE_BUFFER_SIZE, fp)) { if (buf[0] == 'v') { if (buf[1] == ' ') { sscanf(buf, "v %f %f %f", &vertices[curVertex].x, &vertices[curVertex].y, &vertices[curVertex].z ); curVertex++; } else if (buf[1] == 't') { continue; } else if (buf[1] == 'n') { sscanf(buf, "vn %f %f %f", &normals[curNormal].x, &normals[curNormal].y, &normals[curNormal].z ); curNormal++; } } if (buf[0] == 'f') { int v1, v2, v3; int vt1, vt2, vt3; int vn1, vn2, vn3; sscanf(buf, "f %d/%d/%d %d/%d/%d %d/%d/%d", &v1, &vt1, &vn1, &v2, &vt2, &vn2, &v3, &vt3, &vn3 ); memcpy(&faces[curFace].v1.position, &vertices[v1 - 1], sizeof(vec3)); memcpy(&faces[curFace].v2.position, &vertices[v2 - 1], sizeof(vec3)); memcpy(&faces[curFace].v3.position, &vertices[v3 - 1], sizeof(vec3)); memcpy(&faces[curFace].v1.normal, &normals[vn1 - 1], sizeof(vec3)); memcpy(&faces[curFace].v2.normal, &normals[vn2 - 1], sizeof(vec3)); memcpy(&faces[curFace].v3.normal, &normals[vn3 - 1], sizeof(vec3)); curFace++; int numSpaces = 0; for (int i = 0; i < strlen(buf); i++) { if (buf[i] == ' ') { numSpaces++; } } if (numSpaces == 4) { sscanf(buf, "f %d/%d/%d %*d/%*d/%*d %d/%d/%d %d/%d/%d", &v1, &vt1, &vn1, &v2, &vt2, &vn2, &v3, &vt3, &vn3 ); memcpy(&faces[curFace].v1.position, &vertices[v1 - 1], sizeof(vec3)); memcpy(&faces[curFace].v2.position, &vertices[v2 - 1], sizeof(vec3)); memcpy(&faces[curFace].v3.position, &vertices[v3 - 1], sizeof(vec3)); memcpy(&faces[curFace].v1.normal, &normals[vn1 - 1], sizeof(vec3)); memcpy(&faces[curFace].v2.normal, &normals[vn2 - 1], sizeof(vec3)); memcpy(&faces[curFace].v3.normal, &normals[vn3 - 1], sizeof(vec3)); curFace++; } // TODO: textures } } free(vertices); free(normals); fclose(fp); return parsedFile; } void clearParsedFile(ParsedObjFile file) { free(file.faces); }