light: when interpolating a normal that lies outside of a face, recursively look it up on adjacent faces
This commit is contained in:
parent
8c28413a31
commit
c58528499d
|
|
@ -222,6 +222,9 @@ void MakeTnodes(const bsp2_t *bsp);
|
|||
|
||||
/* access the final phong-shaded vertex normal */
|
||||
const vec_t *GetSurfaceVertexNormal(const bsp2_t *bsp, const bsp2_dface_t *f, const int v);
|
||||
|
||||
const bsp2_dface_t *
|
||||
Face_EdgeIndexSmoothed(const bsp2_t *bsp, const bsp2_dface_t *f, const int edgeindex);
|
||||
|
||||
extern float scaledist;
|
||||
extern float rangescale;
|
||||
|
|
@ -300,6 +303,9 @@ Face_TextureName(const bsp2_t *bsp, const bsp2_dface_t *face);
|
|||
void
|
||||
Face_MakeInwardFacingEdgePlanes(const bsp2_t *bsp, const bsp2_dface_t *face, plane_t *out);
|
||||
|
||||
plane_t Face_Plane(const bsp2_t *bsp, const bsp2_dface_t *f);
|
||||
void Face_Normal(const bsp2_t *bsp, const bsp2_dface_t *f, vec3_t norm);
|
||||
|
||||
/* vis testing */
|
||||
const bsp2_dleaf_t *Light_PointInLeaf( const bsp2_t *bsp, const vec3_t point );
|
||||
int Light_PointContents( const bsp2_t *bsp, const vec3_t point );
|
||||
|
|
|
|||
|
|
@ -350,7 +350,8 @@ public:
|
|||
|
||||
std::map<const bsp2_dface_t *, std::vector<vec3_struct_t>> vertex_normals;
|
||||
std::set<int> interior_verts;
|
||||
|
||||
map<const bsp2_dface_t *, set<const bsp2_dface_t *>> smoothFaces;
|
||||
map<int, vector<const bsp2_dface_t *>> vertsToFaces;
|
||||
|
||||
/* given a triangle, just adds the contribution from the triangle to the given vertexes normals, based upon angles at the verts.
|
||||
* v1, v2, v3 are global vertex indices */
|
||||
|
|
@ -381,7 +382,7 @@ static int GetSurfaceVertex(const bsp2_t *bsp, const bsp2_dface_t *f, int v)
|
|||
return bsp->dedges[edge].v[0];
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
Face_Normal(const bsp2_t *bsp, const bsp2_dface_t *f, vec3_t norm)
|
||||
{
|
||||
if (f->side)
|
||||
|
|
@ -411,12 +412,63 @@ FacesOnSamePlane(const std::vector<const bsp2_dface_t *> &faces)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
Vertex_GetPos(const bsp2_t *bsp, int num, vec3_t out)
|
||||
{
|
||||
assert(num >= 0 && num < bsp->numvertexes);
|
||||
const dvertex_t *v = &bsp->dvertexes[num];
|
||||
|
||||
for (int i=0; i<3; i++)
|
||||
out[i] = v->point[i];
|
||||
}
|
||||
|
||||
plane_t
|
||||
Face_Plane(const bsp2_t *bsp, const bsp2_dface_t *f)
|
||||
{
|
||||
const int vertnum = GetSurfaceVertex(bsp, f, 0);
|
||||
vec3_t vertpos;
|
||||
Vertex_GetPos(bsp, vertnum, vertpos);
|
||||
|
||||
plane_t res;
|
||||
Face_Normal(bsp, f, res.normal);
|
||||
res.dist = DotProduct(vertpos, res.normal);
|
||||
return res;
|
||||
}
|
||||
|
||||
const bsp2_dface_t *
|
||||
Face_EdgeIndexSmoothed(const bsp2_t *bsp, const bsp2_dface_t *f, const int edgeindex)
|
||||
{
|
||||
if (smoothFaces.find(f) == smoothFaces.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int v0 = GetSurfaceVertex(bsp, f, edgeindex);
|
||||
int v1 = GetSurfaceVertex(bsp, f, (edgeindex + 1) % f->numedges);
|
||||
|
||||
const auto &v0_faces = vertsToFaces.at(v0);
|
||||
const auto &v1_faces = vertsToFaces.at(v1);
|
||||
|
||||
// find a face f2 that has both verts v0 and v1
|
||||
for (auto f2 : v0_faces) {
|
||||
if (f2 == f)
|
||||
continue;
|
||||
if (find(v1_faces.begin(), v1_faces.end(), f2) != v1_faces.end()) {
|
||||
const auto &f_smoothfaces = smoothFaces.at(f);
|
||||
bool smoothed = (f_smoothfaces.find(f2) != f_smoothfaces.end());
|
||||
return smoothed ? f2 : nullptr;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void
|
||||
CalcualateVertexNormals(const bsp2_t *bsp)
|
||||
{
|
||||
// clear in case we are run twice
|
||||
vertex_normals.clear();
|
||||
interior_verts.clear();
|
||||
smoothFaces.clear();
|
||||
vertsToFaces.clear();
|
||||
|
||||
// read _phong and _phong_angle from entities for compatiblity with other qbsp's, at the expense of no
|
||||
// support on func_detail/func_group
|
||||
|
|
@ -436,7 +488,6 @@ CalcualateVertexNormals(const bsp2_t *bsp)
|
|||
}
|
||||
|
||||
// build "vert index -> faces" map
|
||||
std::map<int, std::vector<const bsp2_dface_t *>> vertsToFaces;
|
||||
for (int i = 0; i < bsp->numfaces; i++) {
|
||||
const bsp2_dface_t *f = &bsp->dfaces[i];
|
||||
for (int j = 0; j < f->numedges; j++) {
|
||||
|
|
@ -455,7 +506,6 @@ CalcualateVertexNormals(const bsp2_t *bsp)
|
|||
printf("CalcualateVertexNormals: %d interior verts\n", (int)interior_verts.size());
|
||||
|
||||
// build the "face -> faces to smooth with" map
|
||||
std::map<const bsp2_dface_t *, std::set<const bsp2_dface_t *>> smoothFaces;
|
||||
for (int i = 0; i < bsp->numfaces; i++) {
|
||||
bsp2_dface_t *f = &bsp->dfaces[i];
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <light/light.h>
|
||||
#include <light/entities.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* ======================================================================== */
|
||||
|
||||
|
|
@ -460,8 +461,10 @@ FractionOfLine(const vec3_t v, const vec3_t w, const vec3_t p) {
|
|||
return t;
|
||||
}
|
||||
|
||||
static void CalcPointNormal(const bsp2_t *bsp, const bsp2_dface_t *face, plane_t surfplane, vec_t *norm, const vec_t *point)
|
||||
static void CalcPointNormal(const bsp2_t *bsp, const bsp2_dface_t *face, vec_t *norm, const vec_t *point, int inside)
|
||||
{
|
||||
plane_t surfplane = Face_Plane(bsp, face);
|
||||
|
||||
// project `point` onto the surface plane (it's hovering 1 unit above)
|
||||
vec3_t pointOnPlane;
|
||||
{
|
||||
|
|
@ -507,6 +510,17 @@ static void CalcPointNormal(const bsp2_t *bsp, const bsp2_dface_t *face, plane_t
|
|||
if (dist < ON_EPSILON) {
|
||||
// behind this plane
|
||||
|
||||
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);
|
||||
v2 = GetSurfaceVertexPoint(bsp, face, (i+1)%face->numedges);
|
||||
|
||||
|
|
@ -620,7 +634,7 @@ CalcPoints(const modelinfo_t *modelinfo, const vec3_t offset, lightsurf_t *surf,
|
|||
|
||||
if (surf->curved)
|
||||
{
|
||||
CalcPointNormal(bsp, face, surf->plane, norm, point);
|
||||
CalcPointNormal(bsp, face, norm, point, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue