From 97a00f0f4197ad3fc4c517e70cb47a956e2da581 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 26 Feb 2017 22:58:08 -0700 Subject: [PATCH] light: avoid recomputing things in CalcPointNormal --- common/mathlib.cc | 13 ++++++++----- include/common/mathlib.hh | 2 +- include/light/phong.hh | 41 +++++++++++++++++++++++++++++++++++++++ light/ltface.cc | 31 ++++++++++++----------------- light/phong.cc | 27 ++++++++++++++++++++++++++ 5 files changed, 89 insertions(+), 25 deletions(-) diff --git a/common/mathlib.cc b/common/mathlib.cc index c9db1c00..1efaf186 100644 --- a/common/mathlib.cc +++ b/common/mathlib.cc @@ -334,21 +334,24 @@ GLM_MakeInwardFacingEdgePlane(const vec3 &v0, const vec3 &v1, const vec3 &faceNo } vector -GLM_MakeInwardFacingEdgePlanes(std::vector points) +GLM_MakeInwardFacingEdgePlanes(const std::vector &points) { - if (points.size() < 3) + const int N = points.size(); + if (N < 3) return {}; vector result; + result.reserve(points.size()); + const vec3 faceNormal = GLM_FaceNormal(points); if (faceNormal == vec3(0,0,0)) return {}; - for (int i=0; i points); std::pair GLM_MakeInwardFacingEdgePlane(const glm::vec3 &v0, const glm::vec3 &v1, const glm::vec3 &faceNormal); -std::vector GLM_MakeInwardFacingEdgePlanes(std::vector points); +std::vector GLM_MakeInwardFacingEdgePlanes(const std::vector &points); bool GLM_EdgePlanes_PointInside(const std::vector &edgeplanes, const glm::vec3 &point); float GLM_EdgePlanes_PointInsideDist(const std::vector &edgeplanes, const glm::vec3 &point); glm::vec3 GLM_TriangleCentroid(const glm::vec3 &v0, const glm::vec3 &v1, const glm::vec3 &v2); diff --git a/include/light/phong.hh b/include/light/phong.hh index d0305ece..67c2aa29 100644 --- a/include/light/phong.hh +++ b/include/light/phong.hh @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -33,6 +34,7 @@ #include #include +#include void CalcualateVertexNormals(const bsp2_t *bsp); const glm::vec3 GetSurfaceVertexNormal(const bsp2_t *bsp, const bsp2_dface_t *f, const int vertindex); @@ -47,4 +49,43 @@ using edgeToFaceMap_t = std::map, std::vector m_points; + std::vector m_normals; + glm::vec4 m_plane; + std::vector m_edgePlanes; + std::vector m_pointsShrunkBy1Unit; + +public: + face_cache_t(const bsp2_t *bsp, const bsp2_dface_t *face, const std::vector &normals) : + m_points(GLM_FacePoints(bsp, face)), + m_normals(normals), + m_plane(Face_Plane_E(bsp, face)), + m_edgePlanes(GLM_MakeInwardFacingEdgePlanes(m_points)), + m_pointsShrunkBy1Unit(GLM_ShrinkPoly(m_points, 1.0f)) + { } + + const std::vector &points() const { + return m_points; + } + const std::vector &normals() const { + return m_normals; + } + const glm::vec4 &plane() const { + return m_plane; + } + const glm::vec3 normal() const { + return glm::vec3(m_plane); + } + const std::vector &edgePlanes() const { + return m_edgePlanes; + } + const std::vector &pointsShrunkBy1Unit() const { + return m_pointsShrunkBy1Unit; + } +}; + +const face_cache_t &FaceCacheForFNum(int fnum); + #endif /* __LIGHT_PHONG_H__ */ diff --git a/light/ltface.cc b/light/ltface.cc index 1d59506c..14f3659a 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -239,16 +239,6 @@ FractionOfLine(const glm::vec3 &v, const glm::vec3 &w, const glm::vec3& p) { return t; } -vector Face_VertexNormals(const bsp2_t *bsp, const bsp2_dface_t *face) -{ - vector normals; - for (int i=0; inumedges; i++) { - const glm::vec3 n = GetSurfaceVertexNormal(bsp, face, i); - normals.push_back(n); - } - return normals; -} - using position_t = std::tuple; constexpr float sampleOffPlaneDist = 1.0f; @@ -270,10 +260,10 @@ PositionSamplePointOnFace(const bsp2_t *bsp, position_t CalcPointNormal(const bsp2_t *bsp, const bsp2_dface_t *face, const glm::vec3 &origPoint, bool phongShaded, float face_lmscale, int recursiondepth) { - const glm::vec4 surfplane = Face_Plane_E(bsp, face); - const auto points = GLM_FacePoints(bsp, face); - const auto normals = Face_VertexNormals(bsp, face); - const auto edgeplanes = GLM_MakeInwardFacingEdgePlanes(points); + const auto &facecache = FaceCacheForFNum(Face_GetNum(bsp, face)); + const glm::vec4 &surfplane = facecache.plane(); + const auto &points = facecache.points(); + const auto &edgeplanes = facecache.edgePlanes(); // project `point` onto the surface plane, then lift it off again const glm::vec3 point = GLM_ProjectPointOntoPlane(surfplane, origPoint) + (vec3(surfplane) * sampleOffPlaneDist); @@ -473,16 +463,17 @@ PositionSamplePointOnFace(const bsp2_t *bsp, const bool phongShaded, const glm::vec3 &point) { - const auto points = GLM_FacePoints(bsp, face); - const auto normals = Face_VertexNormals(bsp, face); + const auto &facecache = FaceCacheForFNum(Face_GetNum(bsp, face)); + const auto &points = facecache.points(); + const auto &normals = facecache.normals(); + const auto &edgeplanes = facecache.edgePlanes(); + const auto &plane = facecache.plane(); - const auto edgeplanes = GLM_MakeInwardFacingEdgePlanes(points); if (edgeplanes.empty()) { // degenerate polygon return {false, nullptr, point, vec3(0)}; } - const auto plane = Face_Plane_E(bsp, face); const float planedist = GLM_DistAbovePlane(plane, point); Q_assert(fabs(planedist - sampleOffPlaneDist) <= POINT_EQUAL_EPSILON); @@ -512,7 +503,7 @@ PositionSamplePointOnFace(const bsp2_t *bsp, const float distanceInside = GLM_EdgePlanes_PointInsideDist(edgeplanes, point); if (distanceInside < 1.0f) { // Point is too close to the border. Try nudging it inside. - const auto shrunk = GLM_ShrinkPoly(points, 1.0f); + const auto &shrunk = facecache.pointsShrunkBy1Unit(); if (!shrunk.empty()) { const pair closest = GLM_ClosestPointOnPolyBoundary(shrunk, point); const vec3 newPoint = closest.second + (sampleOffPlaneDist * vec3(plane)); @@ -670,11 +661,13 @@ CalcPoints(const modelinfo_t *modelinfo, const vec3_t offset, lightsurf_t *surf, TexCoordToWorld(surf->exactmid[0], surf->exactmid[1], &surf->texorg, surf->midpoint); VectorAdd(surf->midpoint, offset, surf->midpoint); +#if 0 // Get faces which could contribute to this one. const auto contribFaces = SetupContributingFaces(bsp, face, GetEdgeToFaceMap()); // Get edge planes of this face which will block light for the purposes of placing the sample points // to avoid light leaks. const auto blockers = BlockingPlanes(bsp, face, GetEdgeToFaceMap()); +#endif surf->width = (surf->texsize[0] + 1) * oversample; surf->height = (surf->texsize[1] + 1) * oversample; diff --git a/light/phong.cc b/light/phong.cc index c643ac35..bf191afe 100644 --- a/light/phong.cc +++ b/light/phong.cc @@ -73,6 +73,7 @@ static map> smoothFaces; static map> vertsToFaces; static map> planesToFaces; static edgeToFaceMap_t EdgeToFaceMap; +static vector FaceCache; const edgeToFaceMap_t &GetEdgeToFaceMap() { @@ -233,6 +234,26 @@ static edgeToFaceMap_t MakeEdgeToFaceMap(const bsp2_t *bsp) return result; } +static vector Face_VertexNormals(const bsp2_t *bsp, const bsp2_dface_t *face) +{ + vector normals; + for (int i=0; inumedges; i++) { + const glm::vec3 n = GetSurfaceVertexNormal(bsp, face, i); + normals.push_back(n); + } + return normals; +} + +static vector MakeFaceCache(const bsp2_t *bsp) +{ + vector result; + for (int i=0; inumfaces; i++) { + const bsp2_dface_t *face = &bsp->dfaces[i]; + result.push_back(face_cache_t{bsp, face, Face_VertexNormals(bsp, face)}); + } + return result; +} + void CalcualateVertexNormals(const bsp2_t *bsp) { @@ -396,4 +417,10 @@ CalcualateVertexNormals(const bsp2_t *bsp) vertex_normals[f].push_back(smoothedNormals[v]); } } + + FaceCache = MakeFaceCache(bsp); +} + +const face_cache_t &FaceCacheForFNum(int fnum) { + return FaceCache.at(fnum); }