Skip to content

Commit

Permalink
Compute surface area for meshes
Browse files Browse the repository at this point in the history
This will be useful for more advanced light sampling methods.
  • Loading branch information
vkoskiv committed Oct 29, 2023
1 parent b7870bc commit c52ce7d
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/datatypes/mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 17 additions & 0 deletions src/utils/loaders/formats/wavefront/wavefront.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit c52ce7d

Please sign in to comment.