167 lines
3.6 KiB
C
167 lines
3.6 KiB
C
#include <GL/glew.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#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);
|
|
} |