light: fix normal interpolation outside the triangle when there are multiple choices of an edge to search across.
This commit is contained in:
parent
e290d844bf
commit
7687e4a927
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue