summaryrefslogtreecommitdiff
path: root/src/extend/mesh.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/extend/mesh.c')
-rw-r--r--src/extend/mesh.c149
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