light: fix normal interpolation outside the triangle when there are multiple choices of an edge to search across.

This commit is contained in:
Eric Wasylishen 2016-05-21 20:29:17 -06:00
parent e290d844bf
commit 7687e4a927
1 changed files with 53 additions and 24 deletions

View File

@ -501,43 +501,72 @@ static void CalcPointNormal(const bsp2_t *bsp, const bsp2_dface_t *face, vec_t *
v2 = v3; v2 = v3;
} }
// not in any triangle // not in any triangle. among the edges this point is _behind_,
// search for the one that the point is least past the endpoints of the edge
{ {
plane_t *edgeplanes = (plane_t *)calloc(face->numedges, sizeof(plane_t)); plane_t *edgeplanes = (plane_t *)calloc(face->numedges, sizeof(plane_t));
Face_MakeInwardFacingEdgePlanes(bsp, face, edgeplanes); Face_MakeInwardFacingEdgePlanes(bsp, face, edgeplanes);
int bestplane = -1;
vec_t bestdist = VECT_MAX;
for (int i=0; i<face->numedges; i++) { for (int i=0; i<face->numedges; i++) {
vec_t dist = DotProduct(point, edgeplanes[i].normal) - edgeplanes[i].dist; vec_t planedist = DotProduct(point, edgeplanes[i].normal) - edgeplanes[i].dist;
if (dist < ON_EPSILON) { if (planedist < ON_EPSILON) {
// behind this plane // behind this plane. check whether we're between the endpoints.
const bsp2_dface_t *smoothed = Face_EdgeIndexSmoothed(bsp, face, i);
if (smoothed) {
if (inside < 3) {
free(edgeplanes);
// call recursively to look up normal in the adjacent face
CalcPointNormal(bsp, smoothed, norm, point, inside + 1);
return;
}
}
v1 = GetSurfaceVertexPoint(bsp, face, i); v1 = GetSurfaceVertexPoint(bsp, face, i);
v2 = GetSurfaceVertexPoint(bsp, face, (i+1)%face->numedges); v2 = GetSurfaceVertexPoint(bsp, face, (i+1)%face->numedges);
vec_t t = FractionOfLine(v1, v2, point); vec3_t v1v2;
t = qmax(qmin(t, 1.0f), 0.0f); VectorSubtract(v2, v1, v1v2);
const vec_t v1v2dist = VectorLength(v1v2);
v1 = GetSurfaceVertexNormal(bsp, face, i); const vec_t t = FractionOfLine(v1, v2, point); // t=0 for point=v1, t=1 for point=v2.
v2 = GetSurfaceVertexNormal(bsp, face, (i+1)%face->numedges);
VectorScale(v2, t, norm); vec_t edgedist;
VectorMA(norm, 1-t, v1, norm); if (t < 0) edgedist = fabs(t) * v1v2dist;
VectorNormalize(norm); else if (t > 1) edgedist = t * v1v2dist;
else edgedist = 0;
free(edgeplanes); if (edgedist < bestdist) {
return; bestplane = i;
bestdist = edgedist;
}
} }
} }
if (bestplane != -1) {
const bsp2_dface_t *smoothed = Face_EdgeIndexSmoothed(bsp, face, bestplane);
if (smoothed) {
// try recursive search
if (inside < 3) {
free(edgeplanes);
// call recursively to look up normal in the adjacent face
CalcPointNormal(bsp, smoothed, norm, point, inside + 1);
return;
}
}
v1 = GetSurfaceVertexPoint(bsp, face, bestplane);
v2 = GetSurfaceVertexPoint(bsp, face, (bestplane+1)%face->numedges);
vec_t t = FractionOfLine(v1, v2, point);
t = qmax(qmin(t, 1.0f), 0.0f);
v1 = GetSurfaceVertexNormal(bsp, face, bestplane);
v2 = GetSurfaceVertexNormal(bsp, face, (bestplane+1)%face->numedges);
VectorScale(v2, t, norm);
VectorMA(norm, 1-t, v1, norm);
VectorNormalize(norm);
free(edgeplanes);
return;
}
free(edgeplanes); free(edgeplanes);
} }