Tools for preprocessing data files from Quake to make them suitable for use on PS1 hardware
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

54 lines
1.4 KiB

#include "common.h"
#include "bsp.h"
#include "face.h"
// Heron's formula, yoinked from: https://www.cuemath.com/measurement/area-of-triangle/
static double face_triangleArea(Vec3 v0, Vec3 v1, Vec3 v2)
{
double a = (v1 - v0).magnitude();
double b = (v2 - v0).magnitude();
double c = (v0 - v2).magnitude();
double s = (a + b + c) * 0.5;
double areaSqr = s * (s - a) * (s - b) * (s - c);
if (areaSqr < FLT_EPSILON) // Collapsed triangles can happen, prevent NaN in that situation
return 0.0;
return sqrt(areaSqr);
}
double face_computeArea(const world_t* world, const face_t* face)
{
int i0, i1, i2;
// Get the first edge so we can build a triangle fan
int edgeIdx = world->edgeList[face->ledge_id];
if (edgeIdx > 0)
{
i0 = world->edges[edgeIdx].vertex0;
i1 = world->edges[edgeIdx].vertex1;
}
else
{
i0 = world->edges[-edgeIdx].vertex1;
i1 = world->edges[-edgeIdx].vertex0;
}
// Triangulate the face, compute the area of each triangle and add them all together
double totalArea = 0.0;
for (int edgeListIdx = 1; edgeListIdx < face->ledge_num - 1; ++edgeListIdx)
{
int edgeIdx = world->edgeList[face->ledge_id + edgeListIdx];
i2 = edgeIdx > 0 ? world->edges[edgeIdx].vertex0 : world->edges[-edgeIdx].vertex1;
Vec3 v0 = world->vertices[i0].toVec();
Vec3 v1 = world->vertices[i1].toVec();
Vec3 v2 = world->vertices[i2].toVec();
totalArea += face_triangleArea(v0, v1, v2);
i1 = i2;
}
return totalArea;
}