Group together equal portals

This commit is contained in:
RaveYard 2022-10-30 14:17:39 +01:00
parent 0a9c2cf131
commit 364d71a24a
3 changed files with 67 additions and 14 deletions

View file

@ -1016,14 +1016,11 @@ std::vector<PortalInfo> GPURaytracer::CreatePortalInfo()
portals.push_back(noPortal); portals.push_back(noPortal);
} }
for (const auto& surface : mesh->surfaces) for (const auto& portal : mesh->portals)
{ {
if (surface->portalIndex >= 0) PortalInfo info;
{ info.Transformation = portal->transformation;
PortalInfo info; portals.push_back(info);
info.Transformation = mesh->portals[surface->portalIndex]->transformation;
portals.push_back(info);
}
} }
return portals; return portals;

View file

@ -563,8 +563,17 @@ int LevelMesh::CreateLinePortal(FLevel& doomMap, const IntLineDef& srcLine, cons
portal->targetSectorGroup = dstLine.GetSectorGroup(); portal->targetSectorGroup = dstLine.GetSectorGroup();
} }
portals.push_back(std::move(portal)); // Deduplicate portals
return int(portals.size() - 1); auto it = portalCache.find(*portal);
if (it == portalCache.end())
{
int id = int(portals.size());
portalCache.emplace(*portal, id);
portals.push_back(std::move(portal));
return id;
}
return it->second;
} }
int LevelMesh::CheckAndMakePortal(FLevel& doomMap, MapSubsectorEx* sub, IntSector* sector, int typeIndex, int plane) int LevelMesh::CheckAndMakePortal(FLevel& doomMap, MapSubsectorEx* sub, IntSector* sector, int typeIndex, int plane)
@ -649,8 +658,17 @@ int LevelMesh::CreatePlanePortal(FLevel& doomMap, const IntLineDef& srcLine, con
portal->targetSectorGroup = dstLine.GetSectorGroup(); portal->targetSectorGroup = dstLine.GetSectorGroup();
} }
portals.push_back(std::move(portal)); // Deduplicate portals
return int(portals.size() - 1); auto it = portalCache.find(*portal);
if (it == portalCache.end())
{
int id = int(portals.size());
portalCache.emplace(*portal, id);
portals.push_back(std::move(portal));
return id;
}
return it->second;
} }
void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side) void LevelMesh::CreateSideSurfaces(FLevel &doomMap, IntSideDef *side)

View file

@ -31,6 +31,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <map>
#include "framework/tarray.h" #include "framework/tarray.h"
#include "framework/halffloat.h" #include "framework/halffloat.h"
@ -92,16 +93,52 @@ struct Portal
return (abs(diff.x) < 0.001 && abs(diff.y) < 0.001 && abs(diff.z) < 0.001); return (abs(diff.x) < 0.001 && abs(diff.y) < 0.001 && abs(diff.z) < 0.001);
} }
// Do the portals travel between the same group of sectors?
/*
inline bool IsTravelingBetweenSameSectorGroupsInEitherDirection(const Portal& portal) const
{
int thisGroupA = sourceSectorGroup < targetSectorGroup ? sourceSectorGroup : targetSectorGroup;
int thisGroupB = sourceSectorGroup > targetSectorGroup ? sourceSectorGroup : targetSectorGroup;
int otherGroupA = portal.sourceSectorGroup < portal.targetSectorGroup ? portal.sourceSectorGroup : portal.targetSectorGroup;
int otherGroupB = portal.sourceSectorGroup > portal.targetSectorGroup ? portal.sourceSectorGroup : portal.targetSectorGroup;
return thisGroupA == otherGroupA && thisGroupB == otherGroupB;
}
*/
// do both portals travel from sector group A to sector group B?
inline bool IsTravelingBetweenSameSectorGroups(const Portal& portal) const
{
return sourceSectorGroup == portal.sourceSectorGroup && targetSectorGroup == portal.targetSectorGroup;
}
}; };
// for use with std::set to recursively go through portals // for use with std::set to recursively go through portals
struct RejectRecursivePortals struct RejectRecursivePortals
{ {
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 bool operator()(const Portal& a, const Portal& b) const
{ {
return !(a.IsInversePortal(b) || a.IsEqualPortal(b)) && std::memcmp(&a.transformation, &b.transformation, sizeof(mat4)) < 0; return !IsEqual(a, 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
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;
} }
}; };
@ -189,6 +226,7 @@ public:
private: private:
std::vector<std::unique_ptr<ThingLight>> portalLights; // Portal generated lights std::vector<std::unique_ptr<ThingLight>> portalLights; // Portal generated lights
std::map<Portal, int, IdenticalPortalComparator> portalCache;
void CreateSubsectorSurfaces(FLevel &doomMap); void CreateSubsectorSurfaces(FLevel &doomMap);
void CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor); void CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor);