diff options
Diffstat (limited to 'src/extend/mesh.c')
-rw-r--r-- | src/extend/mesh.c | 149 |
1 files changed, 148 insertions, 1 deletions
diff --git a/src/extend/mesh.c b/src/extend/mesh.c index a825860..1f393db 100644 --- a/src/extend/mesh.c +++ b/src/extend/mesh.c @@ -1,8 +1,9 @@ #include "mesh.h" +#define GENERATE_TANGNET //#define GENERATE_NORMAL +//#define OPTIMIZE_MESH -#define GENERATE_TANGNET #define LINE_SIZE 1024 @@ -129,6 +130,9 @@ static Mesh *build_mesh( /* obj loader */ /************************************************************************/ +#define SIMPLE_OBJ_LOADER 0 + +#if SIMPLE_OBJ_LOADER Mesh* mesh_loadfromobj(const char *filename) { Vec3 *positions = NULL; Vec2 *texcoords = NULL; @@ -211,5 +215,148 @@ Mesh* mesh_loadfromobj(const char *filename) { return mesh; } +#else + +typedef struct { + int normal_index; + int uv_index; + int index; +} VertexInfo; + +typedef struct { + VertexInfo* vertices; // vertices list +} VertexListElement; + +typedef struct { + int posIndex, normalIndex, uvIndex; +} FaceVertex; + +typedef struct { + FaceVertex vertices[3]; +} FaceInfo; +Mesh* mesh_loadfromobj(const char* path) { + Vec3* position_list = NULL; + Vec3* normal_list = NULL; + Vec2* uv_list = NULL; + VertexListElement* vertex_list = NULL; + FaceInfo* face_list = NULL; + FILE *file; + file = fopen(path, "rb"); + assert(file != NULL); + char line[LINE_SIZE]; + + while (1) { + int items; + if (fgets(line, LINE_SIZE, file) == NULL) { + break; + } + else if (strncmp(line, "v ", 2) == 0) { /* position */ + Vec3 position; + items = sscanf(line, "v %f %f %f", + &position.x, &position.y, &position.z); + assert(items == 3); + darray_push(position_list, position); + // init vertex_list + VertexListElement element = { 0 }; + darray_push(vertex_list, element); + } + else if (strncmp(line, "vt ", 3) == 0) { /* texcoord */ + Vec2 texcoord; + items = sscanf(line, "vt %f %f", + &texcoord.x, &texcoord.y); + assert(items == 2); + darray_push(uv_list, texcoord); + } + else if (strncmp(line, "vn ", 3) == 0) { /* normal */ + Vec3 normal; + items = sscanf(line, "vn %f %f %f", + &normal.x, &normal.y, &normal.z); + assert(items == 3); + darray_push(normal_list, normal); + } + else if (strncmp(line, "f ", 2) == 0) { /* face */ + FaceInfo face; + items = sscanf(line, "f %d/%d/%d %d/%d/%d %d/%d/%d", // only support triangle + &face.vertices[0].posIndex, &face.vertices[0].uvIndex, &face.vertices[0].normalIndex, + &face.vertices[1].posIndex, &face.vertices[1].uvIndex, &face.vertices[1].normalIndex, + &face.vertices[2].posIndex, &face.vertices[2].uvIndex, &face.vertices[2].normalIndex); + assert(items == 9); + darray_push(face_list, face); + } + else + { + // skip + } + } + + int vert_counts = darray_size(vertex_list); + int faceCount = darray_size(face_list); + int normalCount = darray_size(normal_list); + int uvCount = darray_size(uv_list); + + int vert_count = 0; + + Mesh temp_mesh = {0}; + + for (int i = 0; i < darray_size(face_list); ++i) + { + FaceInfo* face = &face_list[i]; + for (int j = 0; j < 3; ++j) + { + FaceVertex face_vert = face->vertices[j]; + int pos_index = face_vert.posIndex - 1; + int normal_index = face_vert.normalIndex - 1; + int uv_index = face_vert.uvIndex - 1; + VertexListElement* vertex = &vertex_list[pos_index]; + if (vertex->vertices) + { + for (int j = 0; j < darray_size(vertex->vertices); ++j) + { + VertexInfo* vert = &vertex->vertices[j]; + if (vert->normal_index == normal_index && vert->uv_index == uv_index) + { + darray_push(temp_mesh.triangles, vert->index); + goto next; + } + } + } + + // create seam + + VertexInfo new_vert; + new_vert.normal_index = normal_index; + new_vert.uv_index = uv_index; + new_vert.index = vert_count; + + darray_push(vertex->vertices, new_vert); + + Vert vert; + vert.position = position_list[pos_index]; + vert.normal = normal_list[normal_index]; + vert.texcoord = uv_list[uv_index]; + vert.index = vert_count; + darray_push(temp_mesh.vertices, vert); + + darray_push(temp_mesh.triangles, vert_count); + + ++temp_mesh.vert_count; + + ++vert_count; + + next: continue; + } + + ++temp_mesh.tris_count; + } + + Mesh* mesh = malloc(sizeof(Mesh)); + mesh->triangles = temp_mesh.triangles; + mesh->vertices = temp_mesh.vertices; + mesh->tris_count = temp_mesh.tris_count; + mesh->vert_count = temp_mesh.vert_count; + + return mesh; +} +#endif
\ No newline at end of file |