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);
}
for (const auto& surface : mesh->surfaces)
for (const auto& portal : mesh->portals)
{
if (surface->portalIndex >= 0)
{
PortalInfo info;
info.Transformation = mesh->portals[surface->portalIndex]->transformation;
portals.push_back(info);
}
PortalInfo info;
info.Transformation = portal->transformation;
portals.push_back(info);
}
return portals;

View file

@ -563,8 +563,17 @@ int LevelMesh::CreateLinePortal(FLevel& doomMap, const IntLineDef& srcLine, cons
portal->targetSectorGroup = dstLine.GetSectorGroup();
}
portals.push_back(std::move(portal));
return int(portals.size() - 1);
// Deduplicate portals
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)
@ -649,8 +658,17 @@ int LevelMesh::CreatePlanePortal(FLevel& doomMap, const IntLineDef& srcLine, con
portal->targetSectorGroup = dstLine.GetSectorGroup();
}
portals.push_back(std::move(portal));
return int(portals.size() - 1);
// Deduplicate portals
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)

View file

@ -31,6 +31,7 @@
#include <memory>
#include <string>
#include <cstring>
#include <map>
#include "framework/tarray.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);
}
// 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
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
{
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:
std::vector<std::unique_ptr<ThingLight>> portalLights; // Portal generated lights
std::map<Portal, int, IdenticalPortalComparator> portalCache;
void CreateSubsectorSurfaces(FLevel &doomMap);
void CreateCeilingSurface(FLevel &doomMap, MapSubsectorEx *sub, IntSector *sector, int typeIndex, bool is3DFloor);