diff options
Diffstat (limited to 'src/extend/mesh.c')
-rw-r--r-- | src/extend/mesh.c | 118 |
1 files changed, 95 insertions, 23 deletions
diff --git a/src/extend/mesh.c b/src/extend/mesh.c index 56b1afe..45a5736 100644 --- a/src/extend/mesh.c +++ b/src/extend/mesh.c @@ -207,16 +207,23 @@ typedef struct { } MeshVertexInfo; typedef struct { + char name[32]; + int start, end; +} SubmeshInfo; + +typedef struct { MeshVertexInfo* vertices; // vertices list Triangle* triangles; // triangles list + SubmeshInfo* submeshs; } MeshInfo; -void free_mesh_info(MeshInfo* mesh) { - for (int i = 0; i < darray_size(mesh->vertices); ++i) { - darray_free(mesh->vertices[i].related_triangles); +void free_mesh_info(MeshInfo* mesh_info) { + for (int i = 0; i < darray_size(mesh_info->vertices); ++i) { + darray_free(mesh_info->vertices[i].related_triangles); } - darray_free(mesh->vertices); - darray_free(mesh->triangles); + darray_free(mesh_info->vertices); + darray_free(mesh_info->triangles); + darray_free(mesh_info->submeshs); } void calc_face_tanget(MeshInfo* mesh); @@ -234,6 +241,10 @@ Mesh* mesh_loadfromobj(const char* path) { file = fopen(path, "rb"); assert(file != NULL); + SubmeshInfo* submeshs = NULL; + SubmeshInfo submesh_info = {0}; + int submesh_start = 0, submesh_end = -1; + char line[LINE_SIZE]; while (1) { @@ -242,7 +253,14 @@ Mesh* mesh_loadfromobj(const char* path) { break; } else if (strncmp(line, "o ", 2) == 0) { /* submesh name */ - // ignore + if(submesh_end >= submesh_start){ + submesh_info.start = submesh_start; + submesh_info.end = submesh_end; + darray_push(submeshs, submesh_info); + submesh_start = submesh_end + 1; + } + items = sscanf(line, "o %s", submesh_info.name); + assert(items == 1); } else if (strncmp(line, "v ", 2) == 0) { /* position */ Vec3 position; @@ -292,13 +310,15 @@ Mesh* mesh_loadfromobj(const char* path) { } else ++p; } - assert(face_verts && darray_size(face_verts) > 0); - FaceVertex* v0 = &face_verts[0]; - for (int i = 1; i < darray_size(face_verts) - 1; ++i) { - FaceVertex* v1 = &face_verts[i]; - FaceVertex* v2 = &face_verts[i + 1]; - FaceInfo face = { *v0, *v1, *v2}; - darray_push(face_list, face); + if (face_verts && darray_size(face_verts) > 0) { + FaceVertex* v0 = &face_verts[0]; + for (int i = 1; i < darray_size(face_verts) - 1; ++i) { + FaceVertex* v1 = &face_verts[i]; + FaceVertex* v2 = &face_verts[i + 1]; + FaceInfo face = { *v0, *v1, *v2 }; + darray_push(face_list, face); + ++submesh_end; + } } darray_free(face_verts); #else @@ -315,7 +335,13 @@ Mesh* mesh_loadfromobj(const char* path) { { // ignore } - memset(&line, 0, LINE_SIZE); + //memset(&line, 0, LINE_SIZE); + } + + if (submesh_end >= submesh_start) { + submesh_info.start = submesh_start; + submesh_info.end = submesh_end; + darray_push(submeshs, submesh_info); } int vert_counts = darray_size(vertex_list); @@ -326,6 +352,7 @@ Mesh* mesh_loadfromobj(const char* path) { int vert_count = 0; MeshInfo mesh_info = {0}; + mesh_info.submeshs = submeshs; for (int i = 0; i < darray_size(face_list); ++i) { @@ -404,19 +431,49 @@ Mesh* mesh_loadfromobj(const char* path) { Mesh* build_mesh(MeshInfo* mesh_info) { Mesh* mesh = malloc(sizeof(Mesh)); - int num_of_face = darray_size(mesh_info->triangles); - mesh->triangles = malloc(num_of_face * 3 * sizeof(uint)); - for (int i = 0; i < darray_size(mesh_info->triangles); ++i) { - mesh->triangles[3 * i] = mesh_info->triangles[i].vertices[0]; - mesh->triangles[3 * i + 1] = mesh_info->triangles[i].vertices[1]; - mesh->triangles[3 * i + 2] = mesh_info->triangles[i].vertices[2]; - } - mesh->tris_count = num_of_face; + // vertices mesh->vertices = malloc(sizeof(Vertex) * darray_size(mesh_info->vertices)); for (int i = 0; i < darray_size(mesh_info->vertices); ++i) { mesh->vertices[i] = mesh_info->vertices[i].props; } mesh->vert_count = darray_size(mesh_info->vertices); + + if(mesh_info->submeshs) { + int num_of_submeshs = darray_size(mesh_info->submeshs); + mesh->submesh = malloc(num_of_submeshs * sizeof(SubMesh)); + mesh->submesh_count = num_of_submeshs; + for (int i = 0; i < darray_size(mesh_info->submeshs); ++i) { + SubmeshInfo* submesh_info = &mesh_info->submeshs[i]; + SubMesh* submesh = &mesh->submesh[i]; + strcpy(submesh->name, submesh_info->name); + int start = submesh_info->start, end = submesh_info->end; + int num_of_face = end - start + 1; + submesh->tris_count = num_of_face; + submesh->triangles = malloc(num_of_face * 3 * sizeof(uint)); + int k = 0; + for(int j = start; j <= end; ++j) { + Triangle* triangle = &mesh_info->triangles[j]; + submesh->triangles[k++] = triangle->vertices[0]; + submesh->triangles[k++] = triangle->vertices[1]; + submesh->triangles[k++] = triangle->vertices[2]; + } + } + // map to first submesh + mesh->triangles = mesh->submesh[0].triangles; + mesh->tris_count = mesh->submesh[0].tris_count; + } else { + mesh->submesh = NULL; + mesh->submesh_count = 0; + int num_of_face = darray_size(mesh_info->triangles); + mesh->triangles = malloc(num_of_face * 3 * sizeof(uint)); + for (int i = 0; i < darray_size(mesh_info->triangles); ++i) { + mesh->triangles[3 * i] = mesh_info->triangles[i].vertices[0]; + mesh->triangles[3 * i + 1] = mesh_info->triangles[i].vertices[1]; + mesh->triangles[3 * i + 2] = mesh_info->triangles[i].vertices[2]; + } + mesh->tris_count = num_of_face; + } + return mesh; } @@ -516,4 +573,19 @@ void calc_vertex_tangnet(MeshInfo* mesh) { } } -#endif // SIMPLE_OBJ_LOADER
\ No newline at end of file +#endif // SIMPLE_OBJ_LOADER + +void free_mesh(Mesh* mesh) { + if(!mesh) return; + + free(mesh->vertices); + if (!mesh->submesh) + { + for (int i = 0; i < mesh->submesh_count; ++i) + free(mesh->submesh[i].triangles); + } + else + { + free(mesh->triangles); + } +} |