diff --git a/src/datatypes/mesh.h b/src/datatypes/mesh.h index 6e6f39d0..31a08a8c 100644 --- a/src/datatypes/mesh.h +++ b/src/datatypes/mesh.h @@ -18,6 +18,7 @@ struct mesh { struct poly *polygons; struct material *materials; struct bvh *bvh; + float surface_area; char *name; int vertex_count; int normal_count; diff --git a/src/utils/loaders/formats/wavefront/wavefront.c b/src/utils/loaders/formats/wavefront/wavefront.c index 7996eda3..ccae4735 100644 --- a/src/utils/loaders/formats/wavefront/wavefront.c +++ b/src/utils/loaders/formats/wavefront/wavefront.c @@ -126,6 +126,18 @@ static void fixIndices(struct poly *p, size_t totalVertices, size_t totalTexCoor } } +float get_poly_area(struct poly *p, struct vector *vertices) { + const struct vector v0 = vertices[p->vertexIndex[0]]; + const struct vector v1 = vertices[p->vertexIndex[1]]; + const struct vector v2 = vertices[p->vertexIndex[2]]; + + const struct vector a = vec_sub(v1, v0); + const struct vector b = vec_sub(v2, v0); + + const struct vector cross = vec_cross(a, b); + return vec_length(cross) / 2.0f; +} + struct mesh *parseWavefront(const char *filePath, size_t *finalMeshCount, struct file_cache *cache) { size_t bytes = 0; char *rawText = loadFile(filePath, &bytes, cache); @@ -171,6 +183,7 @@ struct mesh *parseWavefront(const char *filePath, size_t *finalMeshCount, struct int currentTextureCount = 0; struct poly polybuf[2]; + float surface_area = 0.0f; char *head = firstLine(file); char buf[LINEBUFFER_MAXSIZE]; @@ -205,6 +218,7 @@ struct mesh *parseWavefront(const char *filePath, size_t *finalMeshCount, struct for (size_t i = 0; i < count; ++i) { struct poly p = polybuf[i]; fixIndices(&p, fileVertices, fileTexCoords, fileNormals); + surface_area += get_poly_area(&p, vertices); p.materialIndex = currentMaterialIndex; p.hasNormals = p.normalIndex[0] != -1; polygons[currentPoly++] = p; @@ -242,7 +256,10 @@ struct mesh *parseWavefront(const char *filePath, size_t *finalMeshCount, struct meshes[i].materialCount = 1; } } + + logr(debug, "Mesh %s surface area is %.4fm²\n", currentMeshPtr->name, surface_area); + currentMeshPtr->surface_area = surface_area; currentMeshPtr->polygons = polygons; currentMeshPtr->poly_count = (int)filePolys; currentMeshPtr->vertices = vertices;