#include "loader.h" #include #include #include // STATIC PROTOTYPES static char *GetLine(char *buffer, int maxLength, FILE *fp); static void ComputeNormals(Mesh &mesh); // PUBLIC FUNCTIONS int LoadMesh(char *filename, Mesh &mesh) { FILE *fp; char buffer[256]; char *token; char garbage[5]; fp = fopen(filename, "r"); if (fp == NULL) { fprintf(stderr, "Error loading file: %s\n", filename); return -1; } token = GetLine(buffer, sizeof(buffer), fp); while (token != NULL) { if (token[0] == 'v') { Vertex v; sscanf( token, "%s %f %f %f", garbage, &v.point.x, &v.point.y, &v.point.z); mesh.verts.push_back(v); } else if (token[0] == 'f') { Face f; sscanf(token, "%s %d %d %d", garbage, &f.vertIndex[0], &f.vertIndex[1], &f.vertIndex[2]); // Convert to 0-indexed f.vertIndex[0] -= 1; f.vertIndex[1] -= 1; f.vertIndex[2] -= 1; mesh.faces.push_back(f); } token = GetLine(buffer, sizeof(buffer), fp); } ComputeNormals(mesh); printf("OBJ: %s\n", filename); printf("Verts: %lu\n", mesh.verts.size()); printf("Faces: %lu\n", mesh.faces.size()); mesh.renderData.vertsTransformed.resize(mesh.verts.size()); fclose(fp); return 0; } static char *GetLine(char *buffer, int maxLength, FILE *fp) { while(true) { if (!fgets(buffer, maxLength, fp)) { return NULL; } // for (length = strlen(buffer), index = 0; isspace(buffer[index]); ++index); if (buffer[0] != 'v' && buffer[0] != 'f') { continue; } return buffer; } } static void ComputeNormals(Mesh &mesh) { int *vertexNormalCount = (int*)calloc((size_t)(mesh.verts.size()), sizeof(int)); for (size_t f = 0; f < mesh.faces.size(); ++f) { unsigned int v0 = mesh.faces[f].vertIndex[0]; unsigned int v1 = mesh.faces[f].vertIndex[1]; unsigned int v2 = mesh.faces[f].vertIndex[2]; Vector v01 = mesh.verts[v1].point - mesh.verts[v0].point; Vector v02 = mesh.verts[v2].point - mesh.verts[v0].point; Vector normal = Vector::Cross(v01, v02); // Add each vertex's normal to the sum for future averaging mesh.verts[v0].normal += normal; mesh.verts[v1].normal += normal; mesh.verts[v2].normal += normal; ++vertexNormalCount[v0]; ++vertexNormalCount[v1]; ++vertexNormalCount[v2]; } for (size_t v = 0; v < mesh.verts.size(); ++v) { if (vertexNormalCount[v] > 0) { // Compute the average normal for this vertex mesh.verts[v].normal /= vertexNormalCount[v]; mesh.verts[v].normal.Normalize(); } } }