diff --git a/src/lightmap/levelmesh.cpp b/src/lightmap/levelmesh.cpp index 462dfc6..762975a 100644 --- a/src/lightmap/levelmesh.cpp +++ b/src/lightmap/levelmesh.cpp @@ -178,16 +178,9 @@ void LevelMesh::BuildSmoothingGroups(FLevel& doomMap) printf("Created %d smoothing groups for %d surfaces\n\n", (int)smoothingGroups.size(), (int)surfaces.size()); } - -#include // hack -std::set touchedPortals; - -int depth = 0; - void LevelMesh::PropagateLight(FLevel& doomMap, ThingLight *light) { - // Because of sectorGroups, this will unlikely get this deep anyway - if (depth > 32) + if (lightPropagationRecursiveDepth > 32) { return; } @@ -195,17 +188,17 @@ void LevelMesh::PropagateLight(FLevel& doomMap, ThingLight *light) SphereShape sphere; sphere.center = light->LightRelativeOrigin(); sphere.radius = light->LightRadius(); - depth++; - std::set portalsToErase; + lightPropagationRecursiveDepth++; + std::set portalsToErase; for (int triangleIndex : TriangleMeshShape::find_all_hits(Collision.get(), &sphere)) { Surface* surface = surfaces[MeshSurfaces[triangleIndex]].get(); - // Reject any surface which isn't physically connected to the sector group in which the light resided + + // skip any surface which isn't physically connected to the sector group in which the light resides if (light->sectorGroup == surface->sectorGroup) { if (surface->portalIndex >= 0) { - auto portal = portals[surface->portalIndex].get(); if (touchedPortals.insert(*portal).second) @@ -240,7 +233,8 @@ void LevelMesh::PropagateLight(FLevel& doomMap, ThingLight *light) { touchedPortals.erase(portal); } - depth--; + + lightPropagationRecursiveDepth--; } void LevelMesh::BuildLightLists(FLevel& doomMap) diff --git a/src/lightmap/levelmesh.h b/src/lightmap/levelmesh.h index 8bc6fd6..9c3add9 100644 --- a/src/lightmap/levelmesh.h +++ b/src/lightmap/levelmesh.h @@ -32,6 +32,7 @@ #include #include #include +#include #include "framework/tarray.h" #include "framework/halffloat.h" @@ -154,9 +155,14 @@ public: std::unique_ptr Collision; private: - std::vector> portalLights; // Portal generated lights + // Portal to portals[] index std::map portalCache; + // Portal lights + std::vector> portalLights; + std::set touchedPortals; + int lightPropagationRecursiveDepth = 0; + void CreateSubsectorSurfaces(FLevel &doomMap); void CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor); void CreateFloorSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor); diff --git a/src/lightmap/portal.h b/src/lightmap/portal.h index 4f4fe2a..1adcbe9 100644 --- a/src/lightmap/portal.h +++ b/src/lightmap/portal.h @@ -20,51 +20,54 @@ struct Portal return vec3(v.x, v.y, v.z); } - // Check if the portal is inverse - inline bool IsInversePortal(const Portal& portal) const + // Checks only transformation + inline bool IsInverseTransformationPortal(const Portal& portal) const { auto diff = portal.TransformPosition(TransformPosition(vec3(0))); return abs(diff.x) < 0.001 && abs(diff.y) < 0.001 && abs(diff.z) < 0.001; } - // Check if the portal transformation is equal - inline bool IsEqualPortal(const Portal& portal) const + // Checks only transformation + inline bool IsEqualTransformationPortal(const Portal& portal) const { auto diff = portal.TransformPosition(vec3(0)) - TransformPosition(vec3(0)); return (abs(diff.x) < 0.001 && abs(diff.y) < 0.001 && abs(diff.z) < 0.001); } - // Do both portals travel from sector group A to sector group B? - inline bool IsTravelingBetweenSameSectorGroups(const Portal& portal) const + + // Checks transformation, source and destiantion sector groups + inline bool IsEqualPortal(const Portal& portal) const { - return sourceSectorGroup == portal.sourceSectorGroup && targetSectorGroup == portal.targetSectorGroup; + return sourceSectorGroup == portal.sourceSectorGroup && targetSectorGroup == portal.targetSectorGroup && IsEqualTransformationPortal(portal); + } + + // Checks transformation, source and destiantion sector groups + inline bool IsInversePortal(const Portal& portal) const + { + return sourceSectorGroup == portal.targetSectorGroup && targetSectorGroup == portal.sourceSectorGroup && IsInverseTransformationPortal(portal); + } + + inline void DumpInfo() + { + auto v = TransformPosition(vec3(0)); + printf("Portal offset: %.3f %.3f %.3f\n\tsource group:\t%d\n\ttarget group:\t%d", v.x, v.y, v.z, sourceSectorGroup, targetSectorGroup); } }; -// for use with std::set to recursively go through portals -struct RejectRecursivePortals +// for use with std::set to recursively go through portals and skip returning portals +struct RecursivePortalComparator { - inline bool IsEqual(const Portal& a, const Portal& b) const - { - return a.IsInversePortal(b) || a.IsEqualPortal(b); - } - bool operator()(const Portal& a, const Portal& b) const { - return !IsEqual(a, b) && std::memcmp(&a.transformation, &b.transformation, sizeof(mat4)) < 0; + return !a.IsInversePortal(b) && std::memcmp(&a.transformation, &b.transformation, sizeof(mat4)) < 0; } }; -// for use with std::map to reject portals which have equal transformation between equal sector groups +// for use with std::map to reject portals which have the same effect for light rays struct IdenticalPortalComparator { - inline bool IsEqual(const Portal& a, const Portal& b) const - { - return a.IsEqualPortal(b) && a.IsTravelingBetweenSameSectorGroups(b); - } - bool operator()(const Portal& a, const Portal& b) const { - return !IsEqual(a, b) && std::memcmp(&a.transformation, &b.transformation, sizeof(mat4)) < 0; + return !a.IsEqualPortal(b) && std::memcmp(&a.transformation, &b.transformation, sizeof(mat4)) < 0; } };