Browse Source
Implemented a more accurate face area computation, allowing for more precise tessellation LOD selection.
Implemented a more accurate face area computation, allowing for more precise tessellation LOD selection.
Also started putting face-related functions into a separate source file.master
5 changed files with 69 additions and 30 deletions
-
2PS1BSP.vcxproj
-
6PS1BSP.vcxproj.filters
-
54face.cpp
-
3face.h
-
34main.cpp
@ -0,0 +1,54 @@ |
|||
#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; |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
#pragma once |
|||
|
|||
double face_computeArea(const world_t* world, const face_t* face); |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue